PowerShell for Windows Admins

May 15, 2012  11:37 AM

Test-Connection on PowerShell v3

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Following on from the previous post I performed the same tests on PowerShell v3

The behaviour is the same except that

Test-Connection -ComputerName . -Count 4 –AsJob

now give the 4 pings when you receive the job information

May 14, 2012  3:23 PM

Test-Connection oddities

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

I’ve playing around with Test-Connection because I wanted to set up a long running WMI based job and I thought that pinging a machine lots of times would be a good way to do it. Test-Connection uses the Win32-PingStatus class.

I started with this

PS> Test-Connection -ComputerName . -Count 4

Source        Destination     IPV4Address   IPV6Address  Bytes    Time(ms)
——        ———–     ———–   ———–  —–    ——–
RSLAPTOP01    localhost        ::1          32       0
RSLAPTOP01    localhost        ::1          32       0
RSLAPTOP01    localhost        ::1          32       0
RSLAPTOP01    localhost        ::1          32       0

Nothing special there.

I then tried this

PS> Test-Connection -ComputerName . -Count 4 -Quiet


PS> Test-Connection -ComputerName localhost -Count 4 -Quiet


PS> Test-Connection -ComputerName $env:COMPUTERNAME -Count 4 -Quiet

Very odd – seems like “.” isn’t liked when running –Quiet.  Another good reason to avoid it

I then tried it as a job

PS> Test-Connection -ComputerName . -Count 4 -AsJob

Id       Name     State      HasMoreData   Location     Command
–       —-     —–      ———–   ——–     ——-
3        Job3     Running    False         .            Test-Connection

PS> Get-Job

Id       Name     State      HasMoreData   Location     Command
–       —-     —–      ———–   ——–     ——-
1        Job1     Completed  True          .            Test-Connection
3        Job3     Completed  True          .            Test-Connection

PS> Receive-Job -Id 3

Source   Destination  IPV4Address  IPV6Address  Bytes    Time(ms)
——   ———–  ———–  ———–  —–    ——–
RSLAPTOP01 localhost        ::1       32       0

Only one ping is returned instead of the 4 I was expecting.

Not major problems but something to remember

May 14, 2012  11:21 AM

Scripting Games 2012 comments: #17 opening a csv file

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Some of the events involved creating a CSV file. While it wasn’t explicitly asked that you opened the file many entrants chose to add that code to their scripts.

There were a number of options presented – most involving opening Excel and importing the CSV file.

There is a much quicker way

Invoke-Item -Path test.csv

Invoke-Item causes any file to open in the default application associated with that file.  This will work for Office documents, text files and anything else that you can double click on a get it to open in an application.

If you use Invoke-Item on a .ps1 file – it will open in notepad just as if you’d double clicked it.

May 13, 2012  11:25 AM

Scripting Games 2012 comments: #16 reading environmental variables

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Windows maintains a set of environmental variables. Some, but not all, can be seen via the env: PowerShell drive

Get-ChildItem -Path env:

You can also use WMI to see some of the variables

Get-WmiObject -Class Win32_Environment | ft Name, VariableValue –a

Now how do you read them in your scripts?

I noticed a lot of people doing this

$name = (Get-Item env:\Computername).Value

It works but its a bit long winded.  A better method is this

$name = $env:COMPUTERNAME

$env: is the environment provider surfaced as a namespace

You can also use this technique with other providers e.g.

PS> $variable:MaximumAliasCount

It doesn’t work with all providers e.g. the registry.

May 13, 2012  10:34 AM

TCP/IP Alternative Configuration: pt I The configuration

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

A question on the forum got me wondering about setting the Alternative Configuration on a TCP/IP properties of a network adapter. NICs are normally configured to either DHCP or a static address. If you use DHCP another tab “Alternative Configuration” appears on the IPv4 properties dialog. This can be set to APIPA (an address in the range 169.254.x.x/16 – ie DHCP failed) or a static address. DHCP will be tried first and if it fails the Alternative Configuration kicks in.

I had never seen anything on configuring this so started to dig.

It turns out that the information is held in the registry – big surprise! The data is a little difficult to track down

## http://technet.microsoft.com/en-us/library/bb457118.aspx            
$index = 7            
$HKLM = 2147483650 #HKEY_LOCAL_MACHINE            
$data = @{}            
$nic = Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter "Index=$index"            
$key = "SYSTEM\CurrentControlSet\services\Tcpip\Parameters\Interfaces\$($nic.SettingID)"            
$rc = Invoke-WmiMethod -Class StdRegProv -Name EnumValues -ArgumentList $hklm, $key            
if ($rc.ReturnValue -eq 0) {            
  $num = $rc.Types.count -1            
  for ($i=0; $i -le $num; $i++){            
     switch ($rc.Types[$i]) {            
       1 {$value = Invoke-WmiMethod -Class StdRegProv -Name GetStringValue -ArgumentList $hklm, $key, $($rc.sNames[$i]) | select -ExpandProperty sValue}            
       2 {$value = Invoke-WmiMethod -Class StdRegProv -Name GetExpandedStringValue -ArgumentList $hklm, $key, $($rc.sNames[$i]) | select -ExpandProperty sValue}            
       3 {$value = Invoke-WmiMethod -Class StdRegProv -Name GetBinaryValue -ArgumentList $hklm, $key, $($rc.sNames[$i]) | select -ExpandProperty uValue}            
       4 {$value = Invoke-WmiMethod -Class StdRegProv -Name GetDWORDValue -ArgumentList $hklm, $key, $($rc.sNames[$i]) | select -ExpandProperty uValue}            
       7 {$value = Invoke-WmiMethod -Class StdRegProv -Name GetMultiStringValue -ArgumentList $hklm, $key, $($rc.sNames[$i]) | select -ExpandProperty sValue}            
       default {Write-Warning "Could not process $($rc.sNames[$i]) - type $($rc.Types[$i])"}            
     $data += @{$($rc.sNames[$i]) = $value}            
  }  ## end for            
else {            
 Write-Error "WMI call to registry provider failed"            
$data.GetEnumerator() | sort key

I’ve cheated for now and defined the NIC I’m interested in – Index =7 is my LAN connection.

I need to work with the HKLM hive so define the appropriate constant.

After getting the WMI object for the NIC – filter on Index I use the SettingID to define the registry key I need. The settingID looks like this – {01F4E3B7-5F1F-40BD-8252-DCC3331891C1}

The EnumValues method gives me the registry value names and types for that key. I can loop through them and call the appropriate method to read the registry value.

The data is output sorted by value name and looks like this

Name                           Value

—-                           —–

AddressType                    0

DhcpConnForceBroadcastFlag     0

DhcpGatewayHardware            {192, 168, 1, 1…}

DhcpGatewayHardwareCount       1

DhcpInterfaceOptions           {6, 0, 0, 0…}


EnableDeadGWDetect             1

EnableDHCP                     0


IsServerNapAware               0

Lease                          0

LeaseObtainedTime              1336923004

LeaseTerminatesTime            2147483647


RegisterAdapterName            0
RegistrationEnabled            1

T1                             1336923004

T2                             1336923004

UseZeroBroadcast               0

This shows we have a static address – the fact that IPAddress is set and that EnableDHCP=0

Next time we will look at enabling DHCP and then setting the alternative configuration

May 13, 2012  6:54 AM

PowerShell User Group Recodings

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

A number of the recent UK PowerShell group sessions are available as recordings for download.  The slides and demo scripts are usually included in the download package. They can be downloaded from mu skydrive under the PowerShell User group folder.

The following sessions are available

2011 09 PowerShell remoting and end point customisation
2011 11 Whats new in PowerCLI 5
2011 12 Intro to WMI
2011 12 WSMAN_WMI_and_CIM
2012 January PowerShell v3 CTP 2 overview
2012 February PowerShell and SQL Server
2012 March CIM cmdlets
2012 April Powershell in Windows Server 8

This list will be updated periodically


May 8, 2012  1:22 PM

Scripting Games 2012 comments: #15 pipelines

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

There are a few comments to make about using the pipeline but one of the obvious issues I saw from the games was this type of approach

$p = Get-Process
$p | where {$_.Name -like “powershell*”}

The only time this is valid is if you need to access exactly the same data later in your script.

In all other cases use

Get-Process | where {$_.Name -like “powershell*”}

if you want to split the lines to make it more readable the pipe symbol acts as a line continuation character so

Get-Process |
where {$_.Name -like “powershell*”}

is just as valid

PowerShell is all about the pipeline – use it to your advantage

May 8, 2012  12:00 PM

UK PowerShell Group–May 2012

Richard Siddaway Richard Siddaway Profile: Richard Siddaway


When: Tuesday, May 29, 2012 7:30 PM (BST)

Where: Virtual


This is the second of two meetings dealing with the new PowerShell functionality in Windows Server 8


Richard Siddaway has invited you to attend an online meeting using Live Meeting.
Join the meeting.
Audio Information
Computer Audio
To use computer audio, you need speakers and microphone, or a headset.
First Time Users:
To save time before the meeting, check your system to make sure it is ready to use Microsoft Office Live Meeting.
Unable to join the meeting? Follow these steps:

  1. Copy this address and paste it into your web browser:
  2. Copy and paste the required information:
    Meeting ID: C5C7CT
    Entry Code: P[h/PKJ’7
    Location: https://www.livemeeting.com/cc/usergroups

If you still cannot enter the meeting, contact support

Microsoft Office Live Meeting can be used to record meetings. By participating in this meeting, you agree that your communications may be monitored or recorded at any time during the meeting.

May 7, 2012  10:31 AM

Scripting Games 2012 comments: #14 local computer name

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

There are a number of ways to pass the names of the local machine into a script or function:

  • use the actual name
  • use the IP address (if the processing in the script can work with IP addresses)
  • use – the loop back address (if the processing in the script can work with IP addresses)
  • use a dot  “.”  to signify the local machine
  • use “localhost”
  • use the environmental variable holding the machine name

Normally we don’t use any of the first three because you either have to type out the name – chance of error or the functionality within the script won’t accept IP addresses. Also the PSsession cmdlets only use computer names by default

Traditionally we have used . or localhost especially when working with WMI

Get-WmiObject -Class Win32_OperatingSystem -ComputerName .
Get-WmiObject -Class Win32_OperatingSystem -ComputerName localhost

There are a number of cmdlets that will accept a computer name as a parameter

PS> Get-Help * -Parameter ComputerName | select name


This works:

Get-Process -ComputerName .

but this throws an error

PS> Get-Process -ComputerName localhost
Get-Process : Couldn’t connect to remote machine.
At line:1 char:12
+ Get-Process <<<<  -ComputerName localhost
+ CategoryInfo          : NotSpecified: (:) [Get-Process], InvalidOperationException
+ FullyQualifiedErrorId : System.InvalidOperationException,Microsoft.PowerShell.Commands.GetProcessCommand

I’ve seen similar errors with Get-Eventlog

PS> Get-EventLog -List -ComputerName .

Max(K) Retain OverflowAction        Entries Log
—— —— ————–        ——- —
20,480      0 OverwriteAsNeeded      21,814 Application
512      7 OverwriteOlder              0 DemoMate
20,480      0 OverwriteAsNeeded           0 HardwareEvents
512      7 OverwriteOlder              0 Internet Explorer
20,480      0 OverwriteAsNeeded           0 Key Management Service
8,192      0 OverwriteAsNeeded           3 Media Center
512      7 OverwriteOlder              0 MyNewLog
128      0 OverwriteAsNeeded         357 OAlerts
20,480      0 OverwriteAsNeeded           1 Scripts
20,480      0 OverwriteAsNeeded      56,225 System
15,360      0 OverwriteAsNeeded      10,646 Windows PowerShell
PS> Get-EventLog -List -ComputerName localhost
Get-EventLog : The network path was not found.
At line:1 char:13
+ Get-EventLog <<<<  -List -ComputerName localhost
+ CategoryInfo          : NotSpecified: (:) [Get-EventLog], IOException
+ FullyQualifiedErrorId : System.IO.IOException,Microsoft.PowerShell.Commands.GetEventLogCommand

My solution and recommendation is to use the environmental variable for the computer name.

PS> Get-ChildItem -Path env: | where {$_.name -like “*computer*”}

Name                           Value
—-                           —–
COMPUTERNAME                   RSLAPTOP01

The environment provider doesn’t allow the use of filters so we have to use where

How do we use this:

Get-WmiObject -Class Win32_OperatingSystem -ComputerName $env:COMPUTERNAME
Get-Process -ComputerName $env:COMPUTERNAME
Get-EventLog -List -ComputerName $env:COMPUTERNAME

It can also be used as the default value on a function parameter that asks for a computername – that way you get the local machine if you don’t specify a value to the parameter.

I have never seen this fail – doesn’t mean it can’t just that I’ve never seen it – and it has the advantage of being easier to read than using a dot

May 6, 2012  8:00 AM

Scripting Games 2012 comments: #13 Default Printer

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

In one of the events you had to find the default printer. This can be done using WMI.

The full list of printers can seen using:

Get-WmiObject -Class Win32_Printer

If you want to examine the printer objecy – to determine what information is available – use get-member or select the first printer in the list

Get-WmiObject -Class Win32_Printer | select -f 1 | fl *

you will see that there is a property Default

PS> Get-WmiObject -Class Win32_Printer | Get-Member Default
   TypeName: System.Management.ManagementObject#root\cimv2\Win32_Printer

Name    MemberType Definition
—-    ———- ———-
Default Property   System.Boolean Default {get;set;}

which is Boolean i.e. it has to return true or false

Your first thought might ne to do this:

Get-WmiObject -Class Win32_Printer | where {$_.Default -eq $true}

but it would be better coding practice to do this:

Get-WmiObject -Class Win32_Printer | where {$_.Default}

On the local machine this is OK but if you are working remotely than all of the Win32_Printer objects would be returned and the filtering performed locally. Could be an expensive operation.

The better option is to use the –Filter parameter on Get-WmiObject

Get-WmiObject -Class Win32_Printer -Filter “Default = $true”

this only returns a single  object

If you want to use WQL then it becomes

Get-WmiObject -Query “SELECT * FROM Win32_Printer WHERE Default = $true”

In either case the filtering is done early to reduce the amount of data you are dealing with.

Remember – Filter early & format late

For more information on working with printers see chapter 10 of PowerShell and WMIhttp://www.manning.com/powershellandwmi

Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to: