PowerShell for Windows Admins

Aug 29 2016   1:37PM GMT

Optimising WMI calls–part 1

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Tags:

Recently saw some code where user was running this

$bootupMemory = gwmi -Query “SELECT * FROM Win32_OperatingSystem” -ComputerName $srv
$cpuLoad = gwmi -Query “SELECT * FROM Win32_Processor” -ComputerName $srv

$tSessions = gwmi -Query “SELECT * FROM Win32_TerminalService” -ComputerName $srv

$ima = gwmi -Query “SELECT * FROM Win32_Service WHERE name=’imaservice'” -ComputerName $srv
$mfcom = gwmi -Query “SELECT * FROM Win32_Service WHERE name=’mfcom'” -ComputerName $srv
$ctxPrintMgr = gwmi -Query “SELECT * FROM Win32_Service WHERE name=’cpsvc'” -ComputerName $srv
$msmqstatus = gwmi -Query “SELECT * FROM Win32_Service WHERE name=’msmq'” -ComputerName $srv

$cDrive = gwmi -Query “SELECT * FROM Win32_Logicaldisk WHERE deviceid=’c:'” -ComputerName $srv
$dDrive = gwmi -Query “SELECT * FROM Win32_Logicaldisk WHERE deviceid=’d:'” -ComputerName $srv

against 300 machines.  There were some more calls they involved WMI classes installed by Citrix which I don’t use in my lab

Question was why was it running slow

Two thoughts initially are that repeated calls to Get-WmiObject involve creating, using and removing DCOM connections. This assumes that DCOM isn’t blocked by a firewall or the network. Using a single CIM session should speed up the process.

Secondly making multiple calls to the same class is inefficient.

In addition using the WQL query involves more typing which makes things more difficult to maintain.

Last point is that everyone knows how much I love aliases so you won’t be surprised if I point out that using them is BAD

I don’t have 300 servers in my lab – though using nano server VMs on a machine with 64GB ram you could do that – so I used some PowerShell looping to get round that

Measure-Command -Expression {

$srvs = ‘W16TP5TGT01’, ‘W16TP5TGT02’

for ($i=1; $i -le 150; $i++){

foreach ($srv in $srvs) {
$bootupMemory = gwmi -Query “SELECT * FROM Win32_OperatingSystem” -ComputerName $srv
$cpuLoad = gwmi -Query “SELECT * FROM Win32_Processor” -ComputerName $srv

$tSessions = gwmi -Query “SELECT * FROM Win32_TerminalService” -ComputerName $srv

$ima = gwmi -Query “SELECT * FROM Win32_Service WHERE name=’imaservice'” -ComputerName $srv
$mfcom = gwmi -Query “SELECT * FROM Win32_Service WHERE name=’mfcom'” -ComputerName $srv
$ctxPrintMgr = gwmi -Query “SELECT * FROM Win32_Service WHERE name=’cpsvc'” -ComputerName $srv
$msmqstatus = gwmi -Query “SELECT * FROM Win32_Service WHERE name=’msmq'” -ComputerName $srv

$cDrive = gwmi -Query “SELECT * FROM Win32_Logicaldisk WHERE deviceid=’c:'” -ComputerName $srv
$dDrive = gwmi -Query “SELECT * FROM Win32_Logicaldisk WHERE deviceid=’d:'” -ComputerName $srv
}
}
}

Measure command will run the commands but it reports the time taken rather than the results

I have 2 servers and loop 150 times round connecting to them and getting the results

Some caching of connectivity information occurs but this is close enough

Days              : 0
Hours             : 0
Minutes           : 8
Seconds           : 59
Milliseconds      : 419
Ticks             : 5394194858
TotalDays         : 0.00624328108564815
TotalHours        : 0.149838746055556
TotalMinutes      : 8.99032476333333
TotalSeconds      : 539.4194858
TotalMilliseconds : 539419.4858

A time of just under 9 minutes isn’t bad. This is fast enough to run during the day and can definitely be run over night

But we should be able to do better than that

Lets use a CIM session instead of individual DCOM sessions

Measure-Command -Expression {

$srvs = ‘W16TP5TGT01’, ‘W16TP5TGT02’

for ($i=1; $i -le 150; $i++){

foreach ($srv in $srvs) {
$cs = New-CimSession -ComputerName $srv
$bootupMemory = Get-CimInstance -Query “SELECT * FROM Win32_OperatingSystem” -CimSession $cs
$cpuLoad = Get-CimInstance -Query “SELECT * FROM Win32_Processor” -CimSession $cs

$tSessions = Get-CimInstance -Query “SELECT * FROM Win32_TerminalService” -CimSession $cs

$ima = Get-CimInstance -Query “SELECT * FROM Win32_Service WHERE name=’imaservice'” -CimSession $cs
$mfcom = Get-CimInstance -Query “SELECT * FROM Win32_Service WHERE name=’mfcom'” -CimSession $cs
$ctxPrintMgr = Get-CimInstance -Query “SELECT * FROM Win32_Service WHERE name=’cpsvc'” -CimSession $cs
$msmqstatus = Get-CimInstance -Query “SELECT * FROM Win32_Service WHERE name=’msmq'” -CimSession $cs

$cDrive = Get-CimInstance -Query “SELECT * FROM Win32_Logicaldisk WHERE deviceid=’c:'” -CimSession $cs
$dDrive = Get-CimInstance -Query “SELECT * FROM Win32_Logicaldisk WHERE deviceid=’d:'” -CimSession $cs
Remove-CimSession -CimSession $cs
}
}
}

Time is now

Days              : 0
Hours             : 0
Minutes           : 8
Seconds           : 31
Milliseconds      : 839
Ticks             : 5118397269
TotalDays         : 0.00592407091319444
TotalHours        : 0.142177701916667
TotalMinutes      : 8.530662115
TotalSeconds      : 511.8397269
TotalMilliseconds : 511839.7269

That’s a 5% speed increase for minimal coding effort

Next step is to remove the redundant WMI calls which we’ll do in the next post

 Comment on this Post

 
There was an error processing your information. Please try again later.
Thanks. We'll let you know when a new response is added.
Send me notifications when other members comment.

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:

Share this item with your network: