help optimizing invoke-command script

Hello everyone,

First time poster and a PowerShell novice here. I was thinkering with a script yesterday and got it to work but feel like it can use some optimization. In particular, if I can do this with in a single Invoke-Command call. Any advise would be much appreciated. Here’s the relevant portion of the script:

[pre]

Import-Module ActiveDirectory

$LiveCred = Get-Credential

$IP = Invoke-Command -ComputerName ComputerA -ScriptBlock {

(Get-NetIPConfiguration |
Where-Object {
$.IPv4DefaultGateway -ne $null -and
$
.NetAdapter.Status -ne “Disconnected”
}).IPv4Address.IPAddress

} -credential $LiveCred

$LastBoot = Invoke-Command -ComputerName ComputerA -ScriptBlock {

(Get-CimInstance -ClassName win32_operatingsystem).lastbootuptime

} -credential $LiveCred

[/pre]

 

Some recommendations: Read the Powershell Best Practice and Style Guide please. IMHO Code formatting is crucial for good scripts. Try to avoid too much white space.
You load a module you’re not using later, why? And actually you don’t need to load that in advance at all. Since Powershell verion 3 it will be autoloaded if needed.

$LiveCred = Get-Credential
$Result = Invoke-Command -ScriptBlock {
    $IP = Get-NetIPConfiguration |
        Where-Object {
        $_.IPv4DefaultGateway -ne $null -and
        $_.NetAdapter.Status -ne "Disconnected"
    }
    $OS = Get-CimInstance -ClassName win32_operatingsystem
    [PSCustomObject]@{
        IP             = $IP.IPv4Address.IPAddress
        LastBootUpTime = $OS.lastbootuptime
    }
} -credential $LiveCred
$Result
$Result.IP
$Result.LastBootUpTime

You can combine 2 or more different queries in one Invoke-Command using PSCustomObject. You can access the single properties later like showed here above.

I would use a PSSession as in:

$Session = New-PSSession -ComputerName ComputerA -Credential $LiveCred 

$IP = Invoke-Command -Session $Session -ScriptBlock {
    (Get-NetIPConfiguration | Where-Object {
        $_.IPv4DefaultGateway -ne $null -and
        $_.NetAdapter.Status  -ne 'Disconnected'
    }).IPv4Address.IPAddress
}

$LastBoot = Invoke-Command -Session $Session -ScriptBlock {
    (Get-CimInstance -ClassName win32_operatingsystem).LastBootUpTime
} 

$Session | Remove-PSSession

Use measure-command to compare performance…

… if performance matters … :stuck_out_tongue: :wink: :smiley:

A lil more faster code, if we are considering performance :stuck_out_tongue: .

$Detail = Invoke-Command -Session ComputerA -ScriptBlock {
    $IPaddress      = (Get-NetIPConfiguration | Where-Object {
                            $_.IPv4DefaultGateway -ne $null -and
                            $_.NetAdapter.Status  -ne 'Disconnected'
                       }).IPv4Address.IPAddress
    $LastBootUpTime = (Get-CimInstance -ClassName win32_operatingsystem).LastBootUpTime

    [PSCustomObject]@{
        IPaddress      = $IPaddress
        LastBootUpTime = $LastBootUpTime
    }
}

$Detail.IPaddress
$Detail.LastBootUpTime

Hmm, I think we can tidy this up a little more still:

https://gist.github.com/vexx32/168243502b61e286b1cc7448b09943b1

Wow, you guys are PS wizards. Thanks for your replies and optimization tips. This helps A TON! I’m really glad I posted here.

Thanks again!

D.

Hey, guys–

I tested with both Joel /u/ta11ow and kvprasoon’s suggestions and in each case it worked great. The one thing that boggles me is that Joel’s format is tidier especially for objects with many properties but kvprasoon’s style makes the script a bit faster.

Joel
Job started: 3/29/2019 3:53:00 PM
Job ended: 3/29/2019 3:57:33 PM

kvprasoon
Job started: 3/29/2019 3:58:00 PM
Job ended: 3/29/2019 4:02:23 PM

Can anyone help me understand why that is?

The script is identical with the exception of the Invoke-Command block.

 

 

Hi There!

This is due to Windows Remoting rather then the code execution itself.

Cheers,

PSM

[quote quote=147731]
Joel

Job started: 3/29/2019 3:53:00 PM

Job ended: 3/29/2019 3:57:33 PM

kvprasoon

Job started: 3/29/2019 3:58:00 PM

Job ended: 3/29/2019 4:02:23 PM[/quote]

That’s 4 minutes and 33 seconds vs. 4 minutes and 23 seconds. Would that actually matter? I’d think that could be the measurement tolerance. Did you try it more than once? :wink:

It seems that making function calls within an object delays things ever so slightly.

Olaf, I hear you, that’s right, a few seconds here and there wouldn’t make much of a difference.

Thanks guys much appreciated.

D.