|
Replies:
14
-
Pages:
1
-
Last Post:
Nov 18, 2009 10:09 AM
by: seaJhawk
|
|
|
Posts:
33
Registered:
10/1/09
|
|
|
|
IF condition check pingable machines
Posted:
Nov 10, 2009 10:14 AM
|
|
|
Hello,
I am working on this piece of script (kindly provided by Mr. Levy):
get-content machines.txt | foreach{
$os = gwmi win32_operatingsystem -computer $_ $uptime = (Get-Date) - $os.ConvertToDateTime($os.LastBootUpTime) if($uptime.days -ge XX) { #Forced Shutdown $os.Win32Shutdown(5) #Forced Reboot # $os.Win32Shutdown(6) } }
How can I add an IF condition which checks if the ping on each PC is successfull or not (i.e. the PC is up and running)? I'd prefer to launch the shutdown command only in case the PC is actually reachable over the LAN and I would like to log (append) this kind of info on a txt file.
Thanks a lot! Fabrizio
|
|
|
Posts:
414
Registered:
12/15/08
|
|
|
|
Re: IF condition check pingable machines
Posted:
Nov 10, 2009 11:13 AM
in response to: fabrigatti
|
|
|
Hi Fabrizio,
If the machines are not seperated by a firewall you can usually just use a simple ping. I wrote a function that allows you to specify a timeout and provides an error message rather than just an error status code:
# ping-host function function ping-host ($server, [int] $timeout = 7000){ $ping = gwmi Win32_PingStatus -filter "Address='$($server)' and timeout=$($timeout)" $ping = $ping | Add-Member -passThru -force -memberType NoteProperty -name "StatusText" -value "" switch ($ping.statusCode){ 0 {$ping.StatusText = "Success"}11001 { $ping.StatusText = "Buffer Too Small"} 11002 {$ping.StatusText = "Destination Net Unreachable"}11003 { $ping.StatusText = "Destination Host Unreachable"} 11004 {$ping.StatusText = "Destination Protocol Unreachable"}11005 { $ping.StatusText = "Destination Port Unreachable"} 11006 {$ping.StatusText = "No Resources"}11007 { $ping.StatusText = "Bad Option"} 11008 {$ping.StatusText = "Hardware Error"}11009 { $ping.StatusText = "Packet Too Big"} 11010 {$ping.StatusText = "Request Timed Out"}11011 { $ping.StatusText = "Bad Request"} 11012 {$ping.StatusText = "Bad Route"}11013 { $ping.StatusText = "TimeToLive Expired Transit"} 11014 {$ping.StatusText = "TimeToLive Expired Reassembly"}11015 { $ping.StatusText = "Parameter Problem"} 11016 {$ping.StatusText = "Source Quench"}11017 { $ping.StatusText = "Option Too Big"} 11018 {$ping.StatusText = "Bad Destination"}11032 { $ping.StatusText = "Negotiating IPSEC"} 11050 {$ping.StatusText = "General Failure"} default {$ping.StatusText = "Unknown"} } $ping } You can use it like this:
get-content machines.txt | foreach{
If (ping-host $_){ $os = gwmi win32_operatingsystem -computer $_ $uptime = (Get-Date) - $os.ConvertToDateTime($os.LastBootUpTime) if($uptime.days -ge XX) { #Forced Shutdown $os.Win32Shutdown(5) #Forced Reboot # $os.Win32Shutdown(6) } } Else { # Log error to file here } }
|
|
|
Posts:
33
Registered:
10/1/09
|
|
|
|
Re: IF condition check pingable machines
Posted:
Nov 11, 2009 8:32 AM
in response to: seaJhawk
|
|
|
Hi,
I used the function part as it is, but I changed the remaing part of the script like this:
get-content ShutdownMachines.txt | foreach{ If (ping-host $_){$os = gwmi win32_operatingsystem -computer $_ $uptime = (Get-Date) - $os.ConvertToDateTime($os.LastBootUpTime) if($uptime.days -ge 1) { #Forced Shutdown $os.Win32Shutdown(5)
#Forced Reboot # $os.Win32Shutdown(6)
} } Else { # Log error to file here
Out-File LogShutdownNotPingable.txt -Append
} }
I should get a file with a list of not-reachable machines, right?
None of the running PCs have been shutdown and I got no log files either. These are the error messages I received:
The RPC server is unavailable. (Exception from HRESULT: 0x800706BA) At :line:54 char:11 + $os = gwmi <<<< win32_operatingsystem -computer $_ You cannot call a method on a null-valued expression. At :line:55 char:45 + $uptime = (Get-Date) - $os.ConvertToDateTime <<<< ($os.LastBootUpTime)
I cannot understand that "RPC server is unavailable". The connected PC should be perfectly reachable. I can browse it from a different PC.
|
|
|
Posts:
414
Registered:
12/15/08
|
|
|
|
Re: IF condition check pingable machines
Posted:
Nov 11, 2009 1:32 PM
in response to: fabrigatti
|
|
|
Is the remote computer sitting on the other side of a firewall? Can you ping RPC ports?
Try this:
function Ping-Port([string]$server, [int]$port) { $tcpClient = New-Object System.Net.Sockets.TcpClient trap { # Generic trap object, we don't care what the error is, the check still fails. $False continue; } $tcpClient.Connect($server,$port) if ($tcpClient.Connected) {$True} }
ping-port RemoteComputer 135 ping-port RemoteComputer 445
|
|
|
Posts:
33
Registered:
10/1/09
|
|
|
|
Re: IF condition check pingable machines
Posted:
Nov 12, 2009 2:45 AM
in response to: seaJhawk
|
|
|
The PCs are not behind a firewall. I can ping them from a DOS prompt.
The script above works fine. I get 2 "True" which means that the client is reachable on both ports. In spite of this the first script you attached still ends up with the error I sent.
|
|
|
Posts:
414
Registered:
12/15/08
|
|
|
|
Re: IF condition check pingable machines
Posted:
Nov 12, 2009 8:12 AM
in response to: fabrigatti
|
|
|
In that case I'd say you have an issue with WMI on the remote computer.
Can you run the following on the remote computer:
gwmi win32_operatingsystem
If not then make sure that the WMI service is running on the computer.
If the command does work then * make sure that the Local firewall is not blocking the connection * make sure that the Remote Procedure Call (RPC) service is running
If these are all ok then try running gwmi win32_operatingsystem -computer 192.168.1.2
where the IP address is the IP of the remote computer.
-Chris
|
|
|
Posts:
33
Registered:
10/1/09
|
|
|
|
Re: IF condition check pingable machines
Posted:
Nov 12, 2009 10:14 AM
in response to: seaJhawk
|
|
|
Windows Firewall has been disabled and the PC is not running different local firewalls. RPC is also running.
I ran "gwmi win32_operatingsystem -ComputerName Ipaddress" and I actually got all details of the remote OS.
Then I changed the last part of the script like this (I just changed the -computer parameter into -ComputerName):
get-content ShutdownMachines.txt | foreach{ If (ping-host $_){$os = gwmi win32_operatingsystem -ComputerName $_ $uptime = (Get-Date) - $os.ConvertToDateTime($os.LastBootUpTime) if($uptime.days -ge 01) { #Forced Shutdown $os.Win32Shutdown(5)
#Forced Reboot # $os.Win32Shutdown(6)
} } Else { # Log error to file here
Out-File LogShutdownNotPingable.txt -Append
} }
...But I get the same error I mentioned above. Why does the variable $os seems to be empty?
The out-File command may also be wrong. On the test file "LogShutdownNotPingable.txt" I cannot see any entries, but the file "ShutdownMachines.txt" contains the name of an online machine (to be shutdown) and the name of an offline machine (which should appear in the log file).
|
|
|
Posts:
414
Registered:
12/15/08
|
|
|
|
Re: IF condition check pingable machines
Posted:
Nov 12, 2009 10:24 AM
in response to: fabrigatti
|
|
|
ok - let's take this one step at a time.
So you can do this:
gwmi win32_operatingsystem -computername ipaddress
But you can't do this:
gwmi win32_operatingsystem -computername computername
Correct?
That means you've got a name resolution issue. Do you have "Enable NetBIOS over TCP/IP" on the WINS tab of your network connection IPv4 settings?
|
|
|
Posts:
33
Registered:
10/1/09
|
|
|
|
Re: IF condition check pingable machines
Posted:
Nov 12, 2009 12:47 PM
in response to: seaJhawk
|
|
|
Both commands works. The one with the IP address but also the one with the Computername. It's strange that if inserted in the script they cannot set a value to the variable $os..
|
|
|
Posts:
33
Registered:
10/1/09
|
|
|
|
Re: IF condition check pingable machines
Posted:
Nov 13, 2009 7:56 AM
in response to: seaJhawk
|
|
|
Dear seaJhawk,
I think that the problem is on the following lines:
If (ping-host $_){ $os = gwmi win32_operatingsystem -ComputerName $_ $uptime = (Get-Date) - $os.ConvertToDateTime($os.LastBootUpTime) if($uptime.days -ge 1) { #Forced Shutdown $os.Win32Shutdown(5)
} } If I explicitly write the computername (as you can see below) the PC is powered off correctly! If (ping-host $_){ #$os = gwmi win32_operatingsystem -ComputerName $_ $os = gwmi win32_operatingsystem -ComputerName usrl000111 $uptime = (Get-Date) - $os.ConvertToDateTime($os.LastBootUpTime) ...
What's wrong with the "ping-host" function then?
|
|
|
Posts:
414
Registered:
12/15/08
|
|
|
|
Re: IF condition check pingable machines
Posted:
Nov 17, 2009 11:49 AM
in response to: fabrigatti
|
|
|
Do this to find out what $_ contains after the ping-host:
If (ping-host $_){ $_ }
|
|
|
Posts:
33
Registered:
10/1/09
|
|
|
|
Re: IF condition check pingable machines
Posted:
Nov 18, 2009 3:36 AM
in response to: seaJhawk
|
|
|
Including $_ into the IF I have been using actually shows the name of the machines which is going to be shut down. The script seems to work. I think there were some problems with WINS and/or DNS resolution. What a shame...
However, for not pingable machines, the ELSE part is not executed. Apart from the fact that probably the Out-File command I inserted is wrong, I put a breakpoint on it and it's actually never executed. Whenever I get the error "The WriteObject and WriteError methods cannot be called after the pipeline has been closed. Please contact Microsoft Support Services. At :line:71 char:11 + $os = gwmi <<<< win32_operatingsystem -ComputerName $_" or RPC not available the script execution fails and anything is appended to the log file.
|
|
|
Posts:
414
Registered:
12/15/08
|
|
|
|
Re: IF condition check pingable machines
Posted:
Nov 18, 2009 5:21 AM
in response to: fabrigatti
|
|
|
ok, so I really should have taken my anti-ID10T medicine.
I specifically added a property to the object returned by ping-host so I could see what was going on, but then I neglected to check it.
Try this:
If ((ping-host $_).statusText -eq "success"){ Write-host "Success: $_" } Else{ Write-Host "Failure: $_" } }
|
|
|
Posts:
33
Registered:
10/1/09
|
|
|
|
Re: IF condition check pingable machines
Posted:
Nov 18, 2009 9:53 AM
in response to: seaJhawk
|
|
|
The commands above work fine! I get "Success: computername" in the console is the computer is pingable and "Failure: computername" if it's not.
Last step: I need to export these details into an incremental (i.e. appending) log file. Shouldn't this command work?
Write-host "Success: $_" | Out-File "Pingable.txt" -Append
|
|
|
|
Legend
|
|
MVP: 2501
+
pts
|
|
Guru: 2001
- 2500
pts
|
|
Expert: 751
- 2000
pts
|
|
Enthusiast: 31
- 750
pts
|
|
Novice: 0
- 30
pts
|
|
Moderators
|
|
Helpful answer
(5 pts)
|
|
Answered
(10 pts)
|
|