Advanced Windows PowerShell Scripting Video Training

Advanced Windows PowerShell Scripting Video Training
Advanced Windows PowerShell Scripting Video Training

Tuesday, December 1, 2015

Read The Help Files

One of the things that I urge, if not plead, in my PowerShell classes is to read the help files.  I’ve been working with PowerShell since it was called Monad.  I honestly cannot work with PowerShell unless I use the help system.  One of the reasons why I want IT Pros to read the help files is so they do not “assume” something.  Take this code that I looked at on PowerShell.Com’s forums.

  get-content -path c:\temp\servers.txt |

 foreach {Get-WmiObject win32_service} |

 select pscomputername, displayname, startname


The problem that the IT Pro was having is that the PSComputerName property was always his local client, not the remote computer.  The help file for Get-WMIObject says this about the ComputerName parameter:

-ComputerName [<String[]>]

    Specifies the target computer for the management operation. Enter a fully

    qualified domain name, a NetBIOS name, or an IP address. When the remote

    computer is in a different domain than the local computer, the fully

    qualified domain name is required.


    The default is the local computer. To specify the local computer, such as

    in a list of computer names, use "localhost", the local computer name, or

    a dot (.).


    This parameter does not rely on Windows PowerShell remoting, which uses

    WS-Management. You can use the ComputerName parameter of Get-WmiObject

    even if your computer is not configured to run WS-Management remote



    Required?                    false

    Position?                    named

    Default value                none

    Accept pipeline input?       false

    Accept wildcard characters?  false


The assumption here is that ComputerName would be populated by the name of the computer in the Pipeline.  Two things are wrong here.  The first is that ComputerName parameter is Name, not positional.  It also cannot accept anything from the pipeline.  That means that if you do not type –ComputerName, it will not be used.  Get-WMIObject will execute against the local client.  The other problem is that inside of ForEach-Object, you need to make a reference to the current object in the PowerShell Pipeline.  You do this with $_ or $PSItem  

The site user CMartin16 provided the correct answer to this problem:

 get-content -path c:\temp\servers.txt |

 foreach {Get-WmiObject win32_service -ComputerName $_} |

 select pscomputername, displayname, startname


As an update to this, take a look at Get-CIMInstance and using a CIMSession.  You could also use Invoke-Command and take advantage of PowerShell remoting to contact the remote clients.

Get-Content -Path c:\temp\servers.txt |

 ForEach-Object {Get-CimInstance -ClassName Win32_Service -ComputerName $_} |

 Select-Object -Property pscomputername, displayname, startname


The ComputerName parameter of Get-CIMInstance creates an ad-hoc Session to each client. Here is another example.

Get-CimInstance -ClassName Win32_Service -ComputerName (Get-Content -Path c:\temp\servers.txt)|

Select-Object -Property pscomputername, displayname, startname


An example using PowerShell remoting.

Invoke-Command -ComputerName (Get-Content -Path c:\temp\servers.txt) -ScriptBlock {

    Get-CimInstance -ClassName Win32_Service

}| Select-Object -Property pscomputername, displayname, startname









No comments: