Author Posts

May 28, 2014 at 9:55 am

I am trying to create a powershell script that will do the following:

I have a listing of computer names (stored in C:\temp\powershell\computers.txt) that I need pinged to see if they are online or offline.
1) If the ping responds back with $True (online), I need it to save the computer names into C:\temp\powershell\online\onlinecomputers.txt.
2) IF the ping responds back with $False (offline), I need it to save the computer names into C:\temp\powershell\offline\offlinecomputers.txt
3) I then need to check to see if a running process called "rpc" is running on the machines in the onlinecomputers.txt file.
4) IF "RPC" is not running on the machine, I need the computer name recorded into a txt file (C:\temp\powershell\installsoftware\installsoftware.txt

I read the Learn Windows POwerShell3 in a month of lunches book, but I am getting stuck on the portion of inputting the computer names into a txt file.

So far I have something like this that doesn't work...

$online = @()
$offline = @()
$computers = Get-Content -Path C:\temp\powershell\Computers.txt -Encoding String
If ((Test-Connection -ComputerName $computers -count 1 -Quiet) -eq $true) {
$online += $computer
}
else {
$offline += $Computer
}
$online | out-file "C:\temp\powershell\online\onlinecomputers.txt" -inputobject $computer -Force
$offline | Out-File "C:\temp\powershell\offline\offlinecomputers.txt" -InputObject $computer -Force
$online = $null
$offline = $null

May 28, 2014 at 10:48 am

Seems a bit too complicated to me. Why not test everything in one shot instead of multiple passes. If you want to store it in a file, use an XML file so you can re-import it and query only the data you want later. Take a look at the function below and see what you think. Be sure to look at the examples in the comment based help.


#Requires -Version 3.0
function Test-MrComputer {

< #
.SYNOPSIS
    Tests one or more computers for ICMP (ping) and a specific process. 
 
.DESCRIPTION
    Test-MrComputer is a function that test whether one or more computers are pingable
    and if they are pingable it also test to see if a specific process is running.
 
.PARAMETER ComputerName
    The computer(s) to test. The default is the local computer.
 
.PARAMETER ProcessName
    The name of the process to test whether or not it is running on the tested computer.
 
.EXAMPLE
    Test-MrComputer -ComputerName pc01, pc02, server01 -ProcessName Notepad
 
.EXAMPLE
     Get-Content -Path .\Computers.txt | Test-MrComputer -ProcessName Notepad

.EXAMPLE
     Get-Content -Path .\Computers.txt | Test-MrComputer -ProcessName Notepad | Where-Object {$_.Ping -and $_.Process}
 
.EXAMPLE
     Get-Content -Path .\Computers.txt | Test-MrComputer -ProcessName Notepad | Export-Clixml -Path C:\Scripts\Results.xml
 
.INPUTS
    String
 
.OUTPUTS
    PSCustomObject
 
.NOTES
    Author:  Mike F Robbins
    Website: http://mikefrobbins.com
    Twitter: @mikefrobbins
#>

    [CmdletBinding()]
    param (

        [Parameter(ValueFromPipeline)]
        [ValidateNotNullOrEmpty()]
        [string[]]$ComputerName = $env:COMPUTERNAME,
    
        [Parameter(Mandatory)]
        [string]$ProcessName

    )

    PROCESS {

        foreach ($Computer in $ComputerName) {

            if (Test-Connection -ComputerName $Computer -Count 1 -ErrorAction SilentlyContinue) {
            
                $Ping = $true
            
                if (Get-Process -ComputerName $Computer -Name $ProcessName -ErrorAction SilentlyContinue) {
                    $Process = $true
                }
                else {
                    $Process =$false
                }
                    
            }
            else {
                
                $Ping = $false
                $Process = 'n/a'

            }

            [PSCustomObject]@{    
                ComputerName = $Computer
                Ping = $Ping
                Process = $Process
            }
        }
    }
}

May 28, 2014 at 10:50 am

Try to focus on a more specific topic title when you can... "I need help" pretty much describes everyone here :).

Part of your problem is that you're jamming all of the computer names into a single Test-Connection. That's not going to produce a single True/False, it'll produce multiples, and so it won't know what to do. You need to use a ForEach loop (I would expect) to first enumerate $Computers, so that you can ping one at a time instead of the whole group. The rest of what you've got is a little VBScript-y, but it'll work once you're enumerating them.

It looks like you THINK you're enumerating, because I see you using $computer, but you've not defined $computer anyplace. PowerShell doesn't automagically know that $computer is the singular of $computers; it might was well be $fred and $ethel for all it knows.

Also note that you're using Out-File wrong. If you pipe something to it, that goes to -InputObject. You can't also specify -InputObject as you're doing.