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: ( [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”