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.
If the ping responds back with $True (online), I need it to save the computer names into C:\temp\powershell\online\onlinecomputers.txt.
IF the ping responds back with $False (offline), I need it to save the computer names into C:\temp\powershell\offline\offlinecomputers.txt
I then need to check to see if a running process called “rpc” is running on the machines in the onlinecomputers.txt file.
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…
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
}
}
}
}
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.