Monday, January 9, 2012

Best Practice for PowerShell Functions

 

PowerTip of the Day, from PowerShell.com:

This is a best-practice message: when you create your own function, here are some things you should consider:

- Function name: use cmdlet naming syntax (Verb-Noun), and for verbs, stick to the list of approved verbs. For the noun part, use a meaningful English term, and use singular, not plural. So, don't call a function 'ListNetworkCards' but rather 'Get-NetworkCard'


- Company Prefix: To avoid name collisions, all public functions should use your very own noun-prefix. So don't call your function "Get-NetworkCard" because this generic name might be used elsewhere, too. Instead, pick a prefix for your company. If you work for, let's say, 'Global International', a prefix could be 'GI', and your function name would be "Get-GINetworkCard".


- Standard Parameter Names: Stick to meaningful standard parameter names. Don't call a parameter -PC. Instead, call it


-ComputerName. Don't call it -File. Instead, call it -Path. While there is no official list of approved parameter names, you should get familiar with the parameter names used by the built-in cmdlets to get a feeling for it.

 

Thanks

Finding Standard Parameter Names in PowerShell

 

PowerTip of the Day, from PowerShell.com:

 

In a previous tip, we suggested you to use standard parameter names for your own functions. To get a feeling for what the parameter names are that built-in cmdlets use, here is some code that creates a list of them:

PS> Get-Command -CommandType Cmdlet | Select-Object -ExpandProperty Parameters |  ForEach-Object { $_.Keys } | Group-Object -NoElement | Sort-Object Count, Name -Descending

(...)

   68 Force

   67 Name

   54 InputObject

   54 Credential

   52 Path

   44 PassThru

(...)

"More" Can Be Dangerous - Use Better Alternative in PowerShell

 

PowerTip of the Day, from PowerShell.com:

 

You might know the more.com tool: when you pipe output to more.com, the output is displayed page by page:

PS> Get-EventLog -LogName System | more

However, "more" can be dangerous as you see here. You will not get any results for a long time, and your CPU load increases. more.com first collects all results before it starts paginating it. This takes a long time and a lot of resources.

That's why you should avoid more.com and instead use Out-Host with the parameter -Paging.

PS> Get-EventLog -LogName System | Out-Host -Paging

You immediately see the benefit: results appear momentarily, and no additional CPU load is created.

Creating a "Better" More in PowerShell

 

PowerTip of the Day, from PowerShell.com:

 

In a previous tip you learned that using "more" to paginate output can be dangerous, and instead you should use Out-Host -Paging. To "update" more.com and make it behave like Out-Host with the -Paging parameter set, use a proxy function like this one:

function more {

 param(

 [Parameter(ValueFromPipeline=$true)]

 [System.Management.Automation.PSObject]

 $InputObject

 )

 

 begin

 {

  $type = [System.Management.Automation.CommandTypes]::Cmdlet

  $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Out-Host', $type)

  $scriptCmd = {& $wrappedCmd @PSBoundParameters -Paging }

  $steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin)

  $steppablePipeline.Begin($PSCmdlet)

 }

 process { $steppablePipeline.Process($_) }

 end { $steppablePipeline.End() }

#.ForwardHelpTargetName Out-Host

#.ForwardHelpCategory Cmdlet

}

Once you run it, whenever you use "more", behind the scenes PowerShell will now call "Out-Host -Paging" instead. That's why now, with the new "more" in place, you can safely use lines like this:

PS> Get-EventLog -LogName System | more

Note that your new "more" now works anywhere. The built-in "help" function, for example, also uses the outdated "more.com" and now will work faster, too.

Removing Shares (Remotely, Too) using PowerShell

 

PowerTip of the Day, from PowerShell.com:

 

Removing Shares (Remotely, Too)

In a previous tip you learned how you can create ad-hoc shares using WMI. These shares persist until you remove them again. So if you'd like to clean up behind you, here is a one-liner that removes a share locally or remote:

PS> ([wmi]'\\Storage1\root\cimv2:Win32_Share="Hidden"').Delete()

Just replace "Hidden" with the name of the share you want to delete, and replace "storage1" with the name or IP address of the target system. If you want to delete a share on your local system, remove the server name altogether:

PS> ([wmi]'root\cimv2:Win32_Share="Hidden"').Delete()

 

Thanks

Creating Shares Remotely using Powershell

 

PowerTip of the Day, from PowerShell.com:

 

Let's assume you need to access another machine's file system but there is no network share available. Provided you have local administrator privileges and WMI remoting is allowed in your Firewall, here is a one-liner that adds another share remotely:

PS> ([wmiclass]'\\storage1\root\cimv2:Win32_Share').Create('c:\', 'Hidden', 0, 12, 'secret share').ReturnValue

Just replace "storage1" with the name or IP address of the system you want to access. Note that this method does not allow for separate authentication, so your current user must have local administrator privileges on the target machine.

A return value of 0 indicates success. If you receive a "2", you do not have proper permissions.

thanks

Opening MsgBoxes using PowerShell

 

PowerTip of the Day, from PowerShell.com:

 

eed a quick message box to display something or ask a question? Fortunately, PowerShell can access old COM components. Here's a line that creates a MsgBox for 5 seconds. If the user does not make a choice within that time, it returns -1: a perfect solution for scripts that need to run unattended if no one is around.

$msg = New-Object -ComObject WScript.Shell

$msg.Popup("Hello", 5, "Title", 48)

To find out more about the Popup() method and its arguments, visit:

http://msdn.microsoft.com/en-us/library/x83z1d9f(v=VS.84).aspx

This link documents all the other WSH scripting methods as well

 

Thanks