I'm trying to get the script below to do the following.
$Servers = "Server1", "Server2"
$services = "Service1", "Service2"
$Cred = Get-Credential
foreach ($Server in $Servers)
{
$ip = $Server.Split(" - ")[0]
if (Test-Connection $ip -Count 1 -ErrorAction SilentlyContinue){
Write-Host "$ip is up"
}
else{
Write-Host "$ip is down"
}
}
foreach ($server in $servers) {
Write-Host "Checking services on $server..."
foreach ($service in $services) {
$status = Invoke-Command -ComputerName $servers -Credential $Cred -ScriptBlock {
Get-Service -Name $services -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Status
}
if ($status -eq "Running") {
Write-Host "$service is running on $server"
} else {
Write-Host "$service is not running on $server"
}
}
}
I have tried multiple ways to get this to work, but unfortunately nothing has.
When you do:
$status = Invoke-Command -ComputerName $servers -Credential $Cred -ScriptBlock {
Get-Service -Name $services ....
}
$services
isn't defined in the context of your Invoke-Command
, you should use either $using:
or -ArgumentList
to pass-in the values to the remote scope.
I'd personally also discard the ping tests in your code, a server responding to icmp requests isn't an indication that you can connect to them via Invoke-Command
, this cmdlet can also handle parallel invocation, meaning that the loop on $servers
isn't required.
In summary you could do this:
Invoke-Command -ComputerName $servers -Credential $Cred -ScriptBlock {
Get-Service -Name $using:services -ErrorAction SilentlyContinue |
Select-Object Name, Status
} -ErrorAction SilentlyContinue -ErrorVariable failedToConnect |
Select-Object PSComputerName, Name, Status
And then if you wanted to check which servers you couldn't connect, you can check the variable used in -ErrorVariable
:
# Gives you a list of all servers
$failedToConnect.TargetObject