Invoke-command to run script remotely

I created a script that I would like to run on my remote computers

Script.

Get-WmiObject Win32_Service -ComputerName . |where {($_.startmode -like "*auto*") -and
($_.state -notlike “running”)}|`
select DisplayName,Name,StartMode,State|ft -AutoSize

When I run the script locally I get the results I am looking for.

PS C:\util> .\auto-service.ps1

DisplayName Name StartMode State


Downloaded Maps Manager MapsBroker Auto Stopped
Remote Registry RemoteRegistry Auto Stopped
Software Protection sppsvc Auto Stopped
Windows Biometric Service WbioSrvc Auto Stopped

 

When I run this command

PS C:\util> invoke-command -ComputerName serv021-n1 -FilePath c:\util\auto-service.ps1 out-lineoutput : The value of the repeatHeader data member cannot be null.

  • CategoryInfo : InvalidData: (:slight_smile: [out-lineoutput], ArgumentException
  • FullyQualifiedErrorId : FormatObjectDeserializerNullDataMember,Microsoft.PowerShell.Commands.OutLineOutputComman
    d

If I run this command

PS C:\util> invoke-command -ComputerName serv021-n1 -ScriptBlock {get-service nscp}
Status Name DisplayName PSComputerName


Running nscp NSClient++ Monitoring Agent serv021-n1

That works so I know I have the powershell WINRM setup and remote enabled properly.

I placed the script on the remote server and tried this

PS C:\util> Enter-PSSession -ComputerName SERV021-N1 [SERV021-N1]: PS C:\Users\ME\Documents> cd \util [SERV021-N1]: PS C:\util> .\auto-service.ps1
DisplayName Name StartMode State


Downloaded Maps Manager MapsBroker Auto Stopped
Remote Registry RemoteRegistry Auto Stopped
Software Protection sppsvc Auto Stopped
Windows Biometric Service WbioSrvc Auto Stopped

So that works but I would like to run this on many computers and would not need to copy the script everywhere

 

Any ideas or suggestions

 

Thank you

 

Tom

 

 

 

 

I don’t have winrm enabled to test myself but have you tried something like making a text with computername 1 per line and try something like the following

$computerlist = "c:\path\to\test.txt"
foreach ($pc in $computerlist){
    Invoke-Command -ComputerName $pc -ScriptBlock {
        get-wmiobject win32_service -ComputerName.|where {($_.startmode -like "*auto*") -and ($_.state -notlike "*running*")} |select displayname,name,startmode,state|ft -AutoSize
    }
}

Pretty sure that’s not exactly right but maybe it will get you closer.

For Invoke-Command, if you already have your computernames gathered then you DO NOT want to use a loop. It will run them asynchronously (up to 32 by default in 5.1) against the hosts.

For the original question, the error you’re getting is you are using a formatting command and trying to pull that remotely. Format-* are made for human eyes only so you’d need to run that on your side. Simply change your script to

Get-WmiObject Win32_Service |
    where {$_.startmode -like "*auto*" -and $_.state -notlike "*running*"}|
        select DisplayName,Name,StartMode,State

and then your command to

invoke-command -ComputerName serv021-n1 -FilePath c:\util\auto-service.ps1 | ft -auto

Again, if you have multiple servers simply provide them all to the computername parameter

invoke-command -ComputerName serv021-n1,server2,server3 -FilePath c:\util\auto-service.ps1 | ft -auto

I would also recommend you use the CIM cmdlets over wmi. And if these are scripts to be used by others use the full cmdlet names and parameters, avoid aliases. The end users should be the ones to use Format-* so don’t include those in your scripts. Simply return objects and they can consume those how they need to, whether that is with Format-*, writing to file, uploading to SQL, etc, etc ,etc.

$computerlist = “c:\util\input\servers.txt”
foreach ($pc in $computerlist){
Invoke-Command -ComputerName $pc -ScriptBlock {
get-wmiobject win32_service -ComputerName .| where {($.startmode -like “auto”) -and ($.state -notlike “running”)} | select displayname,name,startmode,state|ft -AutoSize
}
}

PS C:\Util> C:\Util\auto-service.ps1
Invoke-Command : One or more computer names are not valid. If you are trying to pass a URI, use the -ConnectionUri parameter, or pass URI objects instead of strings.
At C:\Util\auto-service.ps1:3 char:5

  • Invoke-Command -ComputerName $pc -ScriptBlock {
  • CategoryInfo : InvalidArgument: (System.String:String) [Invoke-Command], ArgumentException
  • FullyQualifiedErrorId : PSSessionInvalidComputerName,Microsoft.PowerShell.Commands.InvokeCommandCommand

 

the text file only has one server list

SERV021-N1

You set $computerlist to “c:\util\input\servers.txt” not the contents of that file. You need to use Get-Content “c:\util\input\servers.txt”

Doug

 

That worked thanks

 

Off and running now.