PowerShell for Windows Admins


January 24, 2012  4:34 PM

Remoting between PowerShell v3 CTP 2 and PowerShell v2

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

One of the questions on tonight’s Live Meeting concerned the compatibility between remoting on PowerShell v2 and PowerShell v3 CTP 2

The difference is that v3 uses a WSMAN 3.0 stack but v2 uses 2.0

I used two machines:

  • Windows 2008 R2 SP 1 with PowerShell v2
  • Windows 7 SP1 with PowerShell v3 CTP 2

 

on each machine I ensured remoting was enabled then ran

$s = New-PSSession –ComputerName <other computer name>
Invoke-Command -Session $s -ScriptBlock {get-service}

 

it worked in both cases

Looks like in this case you can remote both ways

January 24, 2012  4:07 PM

Recording–UK PowerShell group January 2012

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

The recording of tonight’s meeting together with the slides and demo scripts are available from

https://skydrive.live.com/?cid=43cfa46a74cf3e96#cid=43CFA46A74CF3E96&id=43CFA46A74CF3E96%212469&sc=documents

 

download the zip file from the 2012 January PowerShell v3 CTP2 overview folder

 

Enjoy


January 23, 2012  1:24 PM

Get-CimClass

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Get-CimClass is used to dig into the information available within a WMI class.

At its most basic level we get a set of information like this

PS> Get-CimClass -ClassName Win32_OperatingSystem | fl *

ClassName           : Win32_OperatingSystem
SuperClassName      : CIM_OperatingSystem
CimSuperClassName   : CIM_OperatingSystem
SuperClass          : Microsoft.Management.Infrastructure.CimClass
CimSuperClass       : Microsoft.Management.Infrastructure.CimClass
Namespace           : ROOT/cimv2
Properties          : {Caption, Description, InstallDate, Name…}
CimClassProperties  : {Caption, Description, InstallDate, Name…}
Qualifiers          : {Locale, UUID, dynamic, provider…}
CimClassQualifiers  : {Locale, UUID, dynamic, provider…}
Methods             : {Reboot, Shutdown, Win32Shutdown, Win32ShutdownTracker…}
CimClassMethods     : {Reboot, Shutdown, Win32Shutdown, Win32ShutdownTracker…}
CimSystemProperties : Microsoft.Management.Infrastructure.CimSystemProperties

 

We get a few parameters to work with

PS> Get-Help Get-CimClass

NAME
    Get-CimClass

SYNTAX
    Get-CimClass [[-ClassName] <string>] [[-Namespace] <string>] [-OperationTimeoutSec <UInt32>] [-ComputerName
    <string[]>] [-MethodName <string>] [-PropertyName <string>] [-QualifierName <string>]  [<CommonParameters>]

    Get-CimClass [[-ClassName] <string>] [[-Namespace] <string>] [-OperationTimeoutSec <UInt32>] -CimSession
    <CimSession[]> [-MethodName <string>] [-PropertyName <string>] [-QualifierName <string>]  [<CommonParameters>]

 

Want to know which WMI classes have a method called create

PS> Get-CimClass -MethodName Create

   NameSpace: ROOT/cimv2

ClassName                 Methods              Properties
———                 ——-              ———-
Win32_ShadowStorage       {Create}             {AllocatedSpace, DiffVolume, MaxSpace, UsedSpace…}
Win32_ScheduledJob        {Create, Delete}     {Caption, Description, InstallDate, Name…}
Win32_DfsNode             {Create}             {Caption, Description, InstallDate, Name…}
Win32_BaseService         {StartService, St… {Caption, Description, InstallDate, Name…}
Win32_SystemDriver        {StartService, St… {Caption, Description, InstallDate, Name…}
Win32_Service             {StartService, St… {Caption, Description, InstallDate, Name…}
Win32_TerminalService     {StartService, St… {Caption, Description, InstallDate, Name…}
Win32_Share               {Create, SetShare… {Caption, Description, InstallDate, Name…}
Win32_ClusterShare        {Create, SetShare… {Caption, Description, InstallDate, Name…}
Win32_ShadowCopy          {Create, Revert}     {Caption, Description, InstallDate, Name…}
Win32_Process             {Create, Terminat… {Caption, Description, InstallDate, Name…}

 

or a property called Size

PS> Get-CimClass -PropertyName Size

   NameSpace: ROOT/cimv2

ClassName
———
Win32_DiskDrive
Win32_CDROMDrive
CIM_LogicalDisk
Win32_LogicalDisk
Win32_MappedLogicalDisk
Win32_DiskPartition
Win32_PrintJob

We can dig deeper into a class

Get-CimClass -ClassName Win32_OperatingSystem | select -ExpandProperty Properties

provides an output like this for every property

Name               : CSName
Value              :
CimType            : String
Flags              : Property, ReadOnly, NullValue
Qualifiers         : {CIM_Key, MaxLen, Propagated, read}
ReferenceClassName :

 

Likewise methods

Get-CimClass -ClassName Win32_OperatingSystem | select -ExpandProperty Methods

 

or if you want detail on a particular method

PS> Get-CimClass -ClassName Win32_OperatingSystem | select -ExpandProperty Methods | where name -eq SetDateTime | fl *

Name       : SetDateTime
ReturnType : UInt32
Parameters : {LocalDateTime}
Qualifiers : {Implemented, Privileges, ValueMap}

 

And no thats not a typo on the where statement – its a new PowerShell v3 feature I’ll cover another day

Get-CimClass -ClassName Win32_OperatingSystem  | select -ExpandProperty Qualifiers

and

Get-CimClass -ClassName Win32_OperatingSystem  | select -ExpandProperty CimSystemProperties | fl *

do what you would expect

Finding the key property for a class is a useful exercise

Get-CimClass -ClassName Win32_Process | select -ExpandProperty Properties | where {$_.Qualifiers -like "*key*"}

returns a number of properties – some are like this

Name               : CreationClassName
Value              :
CimType            : String
Flags              : Property, ReadOnly, NullValue
Qualifiers         : {CIM_Key, MaxLen, read}
ReferenceClassName :

 

and have the CIM_Key qualifier but the one we are really interested in is this one

Name               : Handle
Value              :
CimType            : String
Flags              : Property, Key, ReadOnly, NullValue
Qualifiers         : {key, MaxLen, read}
ReferenceClassName :

 

Lots of useful information to be gained from this cmdlet. Don’t leave home to explore WMI without it.


January 22, 2012  7:58 AM

January meeting reminder

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Just a quick reminder that on Tuesday 24 January the UK PowerShell Group presents a Live Meeting looking at PowerShell v3 CTP2

 

Details from here

http://msmvps.com/blogs/richardsiddaway/archive/2012/01/02/uk-powershell-group-january-2012.aspx


January 21, 2012  7:28 AM

SMART disk failure data

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

We can access the SMART disk failure data using

Get-WmiObject -Namespace root\wmi -Class MSStorageDriver_FailurePredictData

 

The important properties are:

Active           : True
InstanceName     : IDE\DiskST9250320AS_____________________________HP07____\5&b0fd174&0&1.0.0_0
Length           : 512
VendorSpecific   : {10, 0, 1, 15…}

 

The data we want is in the VendorSpecific property. On my system its an array of 512 numbers – not very useful but we can (hopefully) decode this

function get-diskstatus {            
[CmdletBinding()]            
param (            
 [string]$computername = $env:COMPUTERNAME            
)            
            
$items = "Unknown1","Unknown2", "Attribute", "Status", "Unknown3", "Value", "Worst", "Raw1", "Raw2", "Unknown4","Unknown5","Unknown6"            
            
$data = Get-WmiObject -Namespace root\wmi -Class MSStorageDriver_FailurePredictData -ComputerName $computername             
            
#$data | select InstanceName, Active            
            
$values = $data.VendorSpecific            
$flb =  $values.Count - ($values.Count % 12) -1            
            
for ($i = 0; $i -le $flb-11; $i += 12  ){            
            
$obj = New-Object -TypeName PSObject            
            
for($j = 0; $j -le 11; $j++) {             
$obj | Add-Member -MemberType Noteproperty -Name $($items[$j]) -Value $($values[$i + $j])            
}            
$obj            
}            
}            

 

We can use this as

get-diskstatus | ft * –a

 

I only have a single disk in my system so this works – I’ll need to modify the function to deal with multiple disks

 

But this is what I get back

 

Unknown1 Unknown2 Attribute Status Unknown3 Value Worst Raw1 Raw2 Unknown4 Unknown5 Unknown6

——– ——– ——— —— ——– —– —– —- —- ——– ——– ——–

      10        0         1     15        0   114    99   62  168       88        4        0

       0        0         3      2        0    99    99    0    0        0        0        0

       0        0         4     51        0    99    99   95    5        0        0        0

       0        0         5     51        0   100   100   17    0        0        0        0

       0        0         7     15        0    81    60  227   94      126        8        0

       0        0         9     50        0    90    90  132   34        0        0        0

       0        0        10     19        0   100   100    0    0        0        0        0

       0        0        12     51        0    99    99  248    4        0        0        0

       0        0       184     51        0   100   100    0    0        0        0        0

       0        0       187     50        0   100   100    0    0        0        0        0

       0        0       188     50        0   100    99   11    0        0        0        0

       0        0       189     58        0   100   100    0    0        0        0        0

       0        0       190     34        0    56    51   44    0       20       45        0

       0        0       191     50        0   100   100   54    0        0        0        0

       0        0       192     50        0   100   100    0    0        0        0        0

       0        0       193     50        0    96    96  166   34        0        0        0

       0        0       194     34        0    44    49   44    0        0        0       16

       0        0       195     26        0    51    49   62  168       88        4        0

       0        0       196     51        0   100   100   17    0        0        0        0

       0        0       197     18        0   100   100    0    0        0        0        0

       0        0       198     16        0   100   100    0    0        0        0        0

       0        0       199     62        0   200   200    0    0        0        0        0

       0        0       254     50        0   100   100    0    0        0        0        0

       0        0         0      0        0     0     0    0    0        0        0        0

       0        0         0      0        0     0     0    0    0        0        0        0

       0        0         0      0        0     0     0    0    0        0        0        0

       0        0         0      0        0     0     0    0    0        0        0        0

       0        0         0      0        0     0     0    0    0        0        0        0

       0        0         0      0        0     0     0    0    0        0        0        0

       0        0         0      0        0     0     0    0    0        0        0        0

       0        0         0      0      200     2     0  115    3        0        1        0

       2       92         3      0        0     0     0    0    0        0        0        0

       0        0         0      0        0     0     0    0    4        1        1        1

       1        1         1      1        1     0     0    0    0        0        0        0

       0        1         0      0        0     0     0    0    0        0        0        0

      54        0         0      0       33   186   100  101  238       28        0        0

       0        0         0      0        1     0   189    1  172      221      133      205

      35        0         0      0      154    12   230  180  219        1        0        0

       0        0         0      0        0   187    32    0    0        0        0        0

       0        0         0      0      105    36     0    0    0        0        0        0

       0        0         0      0        0     0     0    0    0        0        0        0

       0        0         0      0        0     0     0    0    0        0        0        0

 

Next job is to decode some of this information


January 20, 2012  2:58 PM

SMART disks

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

A question on the forum about using WMI to work with SMART disks got my digging into the subject.  SMART disks – http://en.wikipedia.org/wiki/S.M.A.R.T – detect and report on disk problems (hopefully) before they cause a catastrophe. While vendors’ implementations vary there are some things we can access.

The WMI classes are in the root\wmi namespace

PS> Get-WmiObject -Namespace root\wmi -List MSStorageDriver_Failure* | select Name

Name
—-
MSStorageDriver_FailurePredictEvent
MSStorageDriver_FailurePredictFunction
MSStorageDriver_FailurePredictData
MSStorageDriver_FailurePredictThresholds
MSStorageDriver_FailurePredictStatus

 

The most immediate concern is – what is the status of our disks

function test-diskstatus {            
[CmdletBinding()]            
param (            
 [string]$computername = $env:COMPUTERNAME            
)            
            
Get-WmiObject -Namespace root\wmi -Class MSStorageDriver_FailurePredictStatus -ComputerName $computername |            
select InstanceName, Active, PredictFailure, Reason            
            
}

The InstanceName is long so the best display is list

PS> test-diskstatus | fl


InstanceName   : IDE\DiskST9250320AS_____________________________HP07____\5&b0fd174&0&1.0.0_0

Active         : True

PredictFailure : False

Reason         : 0

 

The PredictFailure is the the important property & we worry when it is true!


January 18, 2012  1:54 PM

WMI associations through CIM cmdlets

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

The CIM cmdlets that introduced in PowerShell v3 give us a different API for working with WMI. We can still work with associations just in a slightly different way.

 

NOTE – this done on a different machine to the previous one so the adapters are different

 

We get the instances of a WMI class like this

Get-CimInstance -ClassName Win32_NetworkAdapter

 

we can filter to a specific instance

Get-CimInstance -ClassName Win32_NetworkAdapter -Filter "DeviceId=7"

 

if we put that in a variable

$nic = Get-CimInstance -ClassName Win32_NetworkAdapter -Filter "DeviceId=7"

 

then we can see all of the associated classes like this

Get-CimAssociatedInstance -CimInstance $nic

 

You might think that we would do this to get a specific associated class

Get-CimAssociatedInstance -CimInstance $nic -Association Win32_NetworkAdapterConfiguration

 

Nope – we don’t just to be different.

We need to back track a minute. When two classes are linked there is normally a linking class (reference) the shows the links. We can see this by running

Get-CimClass -ClassName *NetworkAdapter*

which shows a class Win32_NetworkAdapterSetting

so if we try

PS> Get-CimInstance -ClassName Win32_NetworkAdapterSetting

Element                                                     Setting
——-                                                     ——-
Win32_NetworkAdapter (DeviceID = "0")                       Win32_NetworkAdapterConfiguration (Index = 0)
Win32_NetworkAdapter (DeviceID = "1")                       Win32_NetworkAdapterConfiguration (Index = 1)
Win32_NetworkAdapter (DeviceID = "2")                       Win32_NetworkAdapterConfiguration (Index = 2)
Win32_NetworkAdapter (DeviceID = "3")                       Win32_NetworkAdapterConfiguration (Index = 3)
Win32_NetworkAdapter (DeviceID = "4")                       Win32_NetworkAdapterConfiguration (Index = 4)
Win32_NetworkAdapter (DeviceID = "5")                       Win32_NetworkAdapterConfiguration (Index = 5)
Win32_NetworkAdapter (DeviceID = "6")                       Win32_NetworkAdapterConfiguration (Index = 6)
Win32_NetworkAdapter (DeviceID = "7")                       Win32_NetworkAdapterConfiguration (Index = 7)
Win32_NetworkAdapter (DeviceID = "8")                       Win32_NetworkAdapterConfiguration (Index = 8)
Win32_NetworkAdapter (DeviceID = "9")                       Win32_NetworkAdapterConfiguration (Index = 9)
Win32_NetworkAdapter (DeviceID = "10")                      Win32_NetworkAdapterConfiguration (Index = 10)
Win32_NetworkAdapter (DeviceID = "11")                      Win32_NetworkAdapterConfiguration (Index = 11)
Win32_NetworkAdapter (DeviceID = "12")                      Win32_NetworkAdapterConfiguration (Index = 12)

 

Which is cool – we can see the links

A quicker way to discover this linking class is to do

Get-CimClass -ClassName *NetworkAdapter* -Qualifier "Association"

Now how do we use this link

Get-CimAssociatedInstance -CimInstance $nic -Association Win32_NetworkAdapterSetting

ServiceName      DHCPEnabled      Index       Description
———–      ———–      —–       ———–
netvsc           False            7           Microsoft Virtual Machine Bus …

 

which we know from the output above is the correct link

Same answer as WMI using a WQL query or GetRelated – just a different route


January 18, 2012  1:29 PM

Running a function

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Most of my scripts end up being functions because I will eventually combine them into modules

My recent script

function get-logedonuser {                        
param (                        
 [string]$computername = $env:COMPUTERNAME                        
)                        
Get-WmiObject -Class Win32_LogonSession -ComputerName $computername |                        
foreach {                        
 $data = $_                        
                        
 $id = $data.__RELPATH -replace """", "'"                        
 $q = "ASSOCIATORS OF {$id} WHERE ResultClass = Win32_Account"                        
 Get-WmiObject -ComputerName $computername -Query $q |                        
 select @{N="User";E={$($_.Caption)}},                         
 @{N="LogonTime";E={$data.ConvertToDateTime($data.StartTime)}}                        
}                        
}

Prompted a comment about how could you run this script.

First off I would save it to a file – get-logedonuser.ps1

You can then either

Open PowerShell Integrated Scripting Environment (ISE) and the open the file. if you run the file the function is added into memory and you can run it as get-logedonuser

 

OR

open the PowerShell console, change to the folder where you saved the file, and run . ./get-logedonuser.ps1

This “dot sources” the script and leaves the function in memory. Then run get-logedonuser as before


January 18, 2012  1:18 PM

Associated Classes

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

If I run

Get-WmiObject -Class Win32_NetworkAdapter

I get a list of the Network Adapters in my system plus some information about the adapter.  What I don’t get is the IP addressing and other configuration information because it is stored on the Win32_NetworkAdapterConfiguration class.

 

The key property on Win32_NetworkAdapter is DeviceId.  My wireless card is DeviceId 11.

 

There is an association between the Win32_NetworkAdapter class and the corresponding Win32_NetworkAdapterConfiguration class. The Win32_NetworkAdapterConfiguration  class uses Index to identify the card and

Win32_NetworkAdapter.DeviceId = Win32_NetworkAdapterConfiguration.Index

So I could  do this

Get-WmiObject -Class Win32_NetworkAdapter -Filter "DeviceID=11"

Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter "Index=11"

 

A better way is work through the association

$nic = Get-WmiObject -Class Win32_NetworkAdapter -Filter "DeviceID=11"
$nic
$q = "ASSOCIATORS OF {Win32_NetworkAdapter.DeviceID=$($nic.DeviceID)} WHERE ResultClass = Win32_NetworkAdapterConfiguration"
Get-WmiObject -Query $q

 

I tend to use WQL but there is an alternative

$nic = Get-WmiObject -Class Win32_NetworkAdapter -Filter "DeviceID=11"
$nic
$nic.GetRelated("Win32_NetworkAdapterConfiguration")

 

The WMI object has a GetRelated() method

if you just do

$nic.GetRelated()

you will get all associations – its the equivalent of

$q = "ASSOCIATORS OF {Win32_NetworkAdapter.DeviceID=$($nic.DeviceID)} "
Get-WmiObject -Query $q

 

One slight problem is that if you do

$nic | Get-Member

you won’t see the method – you will need to do this

$nic | Get-Member -View base

 

Which one should you use?  Its your choice. I tend to use WQL out of habit but GetRelated() is less typing.


January 17, 2012  3:00 PM

Get the logged on users

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Do you know which users are logged on to your systems?

Want to find out?

function get-logedonuser {            
param (            
 [string]$computername = $env:COMPUTERNAME            
)            
Get-WmiObject -Class Win32_LogonSession -ComputerName $computername |            
foreach {            
 $data = $_            
            
 $id = $data.__RELPATH -replace """", "'"            
 $q = "ASSOCIATORS OF {$id} WHERE ResultClass = Win32_Account"            
 Get-WmiObject -ComputerName $computername -Query $q |            
 select @{N="User";E={$($_.Caption)}},             
 @{N="LogonTime";E={$data.ConvertToDateTime($data.StartTime)}}            
}            
}

 

Use the Win32_LogonSession class and then find the associated Win32_Account classes.  It does work for domain and local accounts


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: