PowerShell for Windows Admins

August 1, 2011  6:57 AM

Where to select

Posted by: Richard Siddaway
PowerShell v2, WMI

Using select-object (aliased to select in common usage) to reduce the number of properties passing into further processing is a common aspect of using PowerShell. However, its not the only place we can do it.

Consider this scenario.

We need to test the network client on a number of remote machines. We can use Win32_NetworkClient

PS > Get-WmiObject -Class Win32_NetworkClient

__GENUS          : 2
__CLASS          : Win32_NetworkClient
__SUPERCLASS     : CIM_LogicalElement
__DYNASTY        : CIM_ManagedSystemElement
__RELPATH        : Win32_NetworkClient.Name="Microsoft Windows Network"
__DERIVATION     : {CIM_LogicalElement, CIM_ManagedSystemElement}
__SERVER         : RSLAPTOP01
__NAMESPACE      : root\cimv2
__PATH           : \\RSLAPTOP01\root\cimv2:Win32_NetworkClient.Name="Microsoft Windows Network"
Caption          : Workstation
Description      : LanmanWorkstation
InstallDate      :
Manufacturer     : Microsoft Corporation
Name             : Microsoft Windows Network
Status           : OK


Now doing this on the local machine is fine but we might want to cut back on the properties returned across the network

PS > Get-WmiObject -Class Win32_NetworkClient -Property Name, Manufacturer, Caption, Description, Status

__GENUS          : 2
__CLASS          : Win32_NetworkClient
__DYNASTY        :
__RELPATH        : Win32_NetworkClient.Name="Microsoft Windows Network"
__DERIVATION     : {}
__SERVER         :
__NAMESPACE      :
__PATH           :
Caption          : Workstation
Description      : LanmanWorkstation
Manufacturer     : Microsoft Corporation
Name             : Microsoft Windows Network
Status           : OK

This cuts down the data a bit – obviously for a class such as Win32_ComputerSystem that has a lot more properties you would get a bigger impact

Compare this to using select-object

PS > Get-WmiObject -Class Win32_NetworkClient |
select -Property Name, Manufacturer, Caption, Description, Status

Name         : Microsoft Windows Network
Manufacturer : Microsoft Corporation
Caption      : Workstation
Description  : LanmanWorkstation
Status       : OK

OK this looks better BUT remember for a remote machine the filtering happens AFTER the object has been returned.

Locally I would use select and remotely I would think about using –property on Get-WmiObject.

As so often it all depends on what you actually need to do

August 1, 2011  6:44 AM

Network client

Posted by: Richard Siddaway

Need to test the network client?

PS (6) > Get-WmiObject -Class Win32_NetworkClient

__GENUS          : 2
__CLASS          : Win32_NetworkClient
__SUPERCLASS     : CIM_LogicalElement
__DYNASTY        : CIM_ManagedSystemElement
__RELPATH        : Win32_NetworkClient.Name="Microsoft Windows Network"
__DERIVATION     : {CIM_LogicalElement, CIM_ManagedSystemElement}
__SERVER         : RSLAPTOP01
__NAMESPACE      : root\cimv2
__PATH           : \\RSLAPTOP01\root\cimv2:Win32_NetworkClient.Name="Microsoft Windows Network"
Caption          : Workstation
Description      : LanmanWorkstation
InstallDate      :
Manufacturer     : Microsoft Corporation
Name             : Microsoft Windows Network
Status           : OK

In a pure Windows environment this won’t give much but if you have a heterogeneous environment with other network clients in the mix it could be useful.

July 31, 2011  9:11 AM

PowerShell Cheat Sheet

Posted by: Richard Siddaway
PowerShell v2

This may be useful for people starting PowerShell. If you can’t remember what punctuation sign does what in PowerShell get a copy of this cheat sheet


July 31, 2011  3:22 AM

Live Mesh Update

Posted by: Richard Siddaway
Windows 7

Couple of points worth noting if you are going to use Live Mesh

(1) File paths longer than 269 characters (folder paths > 248) won’t sync  – shorten the path to fix

(2) PST files won’t sync – even if they are not in use


By default Mesh wants to put the target folder into your Documents area.  The way round it is:

  1. On the source machine open Live Mesh select the folder to synchronise e.g.  c:\scripts
  2. On the target machine create c:\scripts
  3. Open Live Mesh on the target machine
  4. On the folder you want to sync select sync this folder
  5. Select the folder you just created

The synchonisation now happens to the folder you want rather than your profile area.

Otherwise it works as advertised

July 30, 2011  11:03 AM

Live Mesh

Posted by: Richard Siddaway
Windows 7

One problem I’ve had for a while is how to keep my script library synchronised across a number of machines.  I have a laptop I use for my development work at home and I have two netbooks – at least one of which is always with my when I’m away from home.

I’ve tried using robocopy and keeping everything on a USB stick but it just doesn’t work.

Live Mesh may be the answer


I can designate folders to sync and they will sync, including subfolders, across all three machines. The sync is in both directions.

Good price point as well!

Not something to contemplate for the enterprise but a good solution for private use.

This doesn’t necessarily take away the need for a backup but it does reduce the pressure on backups as I can accept rebuilding the machine and re-installing software. Its the data I can’t afford to lose.

July 29, 2011  3:08 PM

Network Adapter speed and duplex

Posted by: Richard Siddaway
Network, PowerShell v2, WMI

One thing that can cause problems on the network is the duplex setting on the network adapter.  If this doesn’t match the switch port then at best you will get performance issues and at worst no connectivity.

The speed of the connection can be obtained from Win32_NetworkAdapter but for the duplex setting we need to go to the registry.

function test-duplex {            
param (            
BEGIN {            
 $HKLM = 2147483650            
 $reg = [wmiclass]"\\$computer\root\default:StdRegprov"            
 $keyroot = "SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}"            
PROCESS {            
Get-WmiObject -Class Win32_NetworkAdapterConfiguration -ComputerName $computer -Filter "IPEnabled='$true'" |            
foreach {            
$data = $_.Caption -split "]"            
$suffix = $data[0].Substring(($data[0].length-4),4)            
$key = $keyroot + "\$suffix"            
$value = "*PhysicalMediaType"            
$pmt = $reg.GetDwordValue($HKLM, $key, $value)  ## REG_DWORD            
## 0=Unspecified, 9=Wireless, 14=Ethernet            
if ($pmt.uValue -eq 14){            
$nic = $_.GetRelated("Win32_NetworkAdapter") | select Speed, NetConnectionId            
$value = "*SpeedDuplex"            
$dup = $reg.GetStringValue($HKLM, $key, $value)  ## REG_SZ            
switch ($dup.sValue) {            
 "0" {$duplex = "Auto Detect"}            
 "1" {$duplex = "10Mbps \ Half Duplex"}            
 "2" {$duplex = "10Mbps \ Full Duplex"}            
 "3" {$duplex = "100Mbps \ Half Duplex"}            
 "4" {$duplex = "100Mbps \ Full Duplex"}            
New-Object -TypeName PSObject -Property @{            
  NetworkConnector = $($nic.NetConnectionID )            
  DuplexSetting = $duplex            
  Speed = $($nic.Speed)            
} #if            
} #foreach            
} #process            
} #function

Start by defining the information we need to read the registry

Get the Win32_NetworkAdapterConfiguration for those adapters that are IP enabled. We then test the physical media type and if its ethernet we get the duplex setting. The nework connectioid is retrieved to identify the card and an object is created to pull the output together

July 28, 2011  9:56 AM

The New IT?

Posted by: Richard Siddaway

A recent headline asked “How will you fit into the New IT?”

My answer is what new IT?

I have been working in IT for well over 20 years and in that time I can’t remember a period when there wasn’t a significant change coming:

  • introduction of PCs
  • growth of networks
  • Internet
  • Rise of Windows and fall of Novell
  • Token ring giving way to Ethernet
  • Viruses and other malware
  • Virtualisation

The so called new IT is the “cloud” and all its ramifications. We’ve been hosting applications elsewhere for years but all of a sudden its the only way to run your IT shop – at least according to the experts in the computer press. When was the last time one of these pundits actually worked in IT – if they ever did.

IT is constantly changing – if you don’t realise that and can’t live with it you shouldn’t be in the industry. An IT professional’s job is to work out which of the changes are beneficial to their organisation and which are a distraction.

No matter what the “experts” tell you there is no single answer that fits every organisation – pick whats needed and disregard the rest.

The only constant is change

July 27, 2011  2:54 AM

Just a thought

Posted by: Richard Siddaway
PowerShell v2, WMI

I’ve working with WMI a lot recently and frequently seen things like this

Get-WmiObject -Class Win32_OperatingSystem -ComputerName dc02

Get-WmiObject -Class Win32_ComputerSystem -ComputerName dc02

Get-WmiObject -Class Win32_LogicalDisk -ComputerName dc02

Each of these has to create a connection


$sb = {
Get-WmiObject -Class Win32_OperatingSystem
Get-WmiObject -Class Win32_ComputerSystem
Get-WmiObject -Class Win32_LogicalDisk

Invoke-Command -ScriptBlock $sb -ComputerName dc02

more efficient

In some cases yes depending on what you want to do with the information. Especially if need to filter data

July 24, 2011  12:13 PM

PowerShell remoting–User group meeting

Posted by: Richard Siddaway
PowerShell, User Group

Final reminder for the user group meeting on Tuesday 26 July

Details from:


July 22, 2011  1:43 PM

Can I? Should?–copying VBscripts

Posted by: Richard Siddaway
Operating System, WMI

One of the major errors I see PowerShell newcomers performing is copying script structures and syntax of VBScript into PowerShell. Let me give you an example

This piece of VBScript is borrowed from the Windows 2000 scripting guide


strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colSettings = objWMIService.ExecQuery _
("SELECT * FROM Win32_OperatingSystem")
For Each objOperatingSystem in colSettings
Wscript.Echo "OS Name: " & objOperatingSystem.Name
Wscript.Echo "Version: " & objOperatingSystem.Version
Wscript.Echo "Service Pack: " & _
objOperatingSystem.ServicePackMajorVersion _
& "." & objOperatingSystem.ServicePackMinorVersion
Wscript.Echo "OS Manufacturer: " & objOperatingSystem.Manufacturer
Wscript.Echo "Windows Directory: " & _
Wscript.Echo "Locale: " & objOperatingSystem.Locale
Wscript.Echo "Available Physical Memory: " & _
Wscript.Echo "Total Virtual Memory: " & _
Wscript.Echo "Available Virtual Memory: " & _
Wscript.Echo "OS Name: " & objOperatingSystem.SizeStoredInPagingFiles

It uses the Win32_OperatingSystem class to display information about the computers OS. As you can see the bulk of the script is concerned with formatting. Note the error in the script regarding OS Name


What often happens is that this will be translated directly, line by line, into PowerShell – which gives us something like this

$strComputer = "."            
$colSettings = Get-WmiObject -Query "SELECT * FROM Win32_OperatingSystem" -ComputerName $strComputer            
foreach ($objOperatingSystem in $colSettings){            
 Write-Host "OS Name: "  $objOperatingSystem.Name            
 Write-Host "Version: "  $objOperatingSystem.Version            
 Write-Host "Service Pack: "  $objOperatingSystem.ServicePackMajorVersion "." $objOperatingSystem.ServicePackMinorVersion            
 Write-Host "OS Manufacturer: "  $objOperatingSystem.Manufacturer            
 Write-Host "Windows Directory: "  $objOperatingSystem.WindowsDirectory            
 Write-Host "Locale: "  $objOperatingSystem.Locale            
 Write-Host "Available Physical Memory: "  $objOperatingSystem.FreePhysicalMemory            
 Write-Host "Total Virtual Memory: "  $objOperatingSystem.TotalVirtualMemorySize            
 Write-Host "Available Virtual Memory: " $objOperatingSystem.FreeVirtualMemory            

This is less code but still seems like a lot of work


lets put it into PowerShell as if we had written it from scratch

$strComputer = "."            
Get-WmiObject -Class Win32_OperatingSystem -ComputerName $strComputer |            
select Name, Version, ServicePackMajorVersion, ServicePackMinorVersion,            
Manufacturer, WindowsDirectory, Locale, FreePhysicalMemory,             
TotalVirtualMemorySize, FreeVirtualMemory


Now that is much easier. Quicker to code and easier to understand.


By all means use VBscripts as references for using WMI classes (I do) but re-write into PowerShell its much, much easier.

This isn’t a contradiction of my previous post as I advocated leaving legacy VBScript alone until you needed to  modify it

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: