Reputation: 9
I use PowerShell often to do automated batch patching. I normally have to get a list of machines, ping test, take the output of that file and put it into PowerShell, move the files, and then I use PSEXEC
to execute the bat file. (I can't use PowerShell to remote execute, WinRM is blocked in my world).
I found a nice script for removing users from groups that pings and if there is no response, move on, but if there is, it executes the command and moves to the next. I'm trying to adapt that for my own uses to ping, move files, and if there's no response, move on. It looks like as of now, the script is pinging, moving, and if there's no response, it errors out with "Network Path Not Found".
My PS script is as follows:
#Install Cisco AnyConnect Core VPN and ISE Posture Installation
#Author: Erik R. Little
#Creation Date: 1 November 2017
#This script will do the following actions:
#1.- Get a computer list from a TXT file.
#2.- Do a ping to every computer on the list, if the computer is offline it will skip it and pass to the next one.
#3.- If the computer answers the ping it will push the AnyConnect installation files to the remote machine.
#4.- Creates a log with all the transactions.
# Log Time Variables
$Date = Get-Date -UFormat %b-%m-%Y
$Hour = (Get-Date).Hour
$Minuntes = (Get-Date).Minute
$Log = "C:\support\cisco\Log Files\AnyConnect Install-" + $Date + "-" + $Hour + "-" + $Minuntes + ".log"
#Creates a log file for this process.
Start-Transcript -Path $Log -Force
#List of computers to be check
$ComputerNames = Get-Content "C:\support\cisco\Computers.txt"
#Ping the computers on the list
foreach ($ComputerName in $ComputerNames) {
if (-not (Test-Connection $ComputerName -Quiet -Count 1 -ErrorAction Continue)) {
#If theres no ping answer pass to the next one
Write-Output "Computer $ComputerName not reachable (PING) - Skipping this computer..."
} else {
#If computer does answer the ping
Write-Output "Computer $ComputerName is online"
}
}
foreach ($ComputerName in $ComputerNames) {
Write-Host $ComputerName
if ((Test-Path "\\$ComputerName\c$\support\cisco") -eq 0) {
mkdir "\\$ComputerName\c$\support\cisco"
robocopy /mir "C:\support\cisco" "\\$ComputerName\c$\support\cisco"
} elseif ((Test-Path "\\$ComputerName\c$\support\cisco") -eq 1) {
robocopy /mir "C:\support\cisco" "\\$ComputerName\c$\support\cisco"
}
}
}
}
Stop-Transcript
So to sum up: I want the script to ping and move on if there's no response, but if there is a ping, move the file, and then move to the next.
Upvotes: 0
Views: 1857
Reputation: 13237
Using a single foreach
.
I've also updated your logic for Test-Connection
and Test-path
so the code is cleaner.
#Creates a log file for this process.
Start-Transcript -Path $Log -Force
#List of computers to be check
$ComputerNames = Get-Content "C:\support\cisco\Computers.txt"
foreach ($ComputerName in $ComputerNames) {
if (Test-Connection $ComputerName -Quiet -Count 1 -ErrorAction Continue ) {
Write-Output "Computer $ComputerName is online"
if (Test-path "\\$ComputerName\c$\support\cisco") {
robocopy /mir "C:\support\cisco" "\\$ComputerName\c$\support\cisco"
}
else {
mkdir "\\$ComputerName\c$\support\cisco"
robocopy /mir "C:\support\cisco" "\\$ComputerName\c$\support\cisco"
}
}
Else {
Write-Output "Computer $ComputerName not reachable (PING) - Skipping this computer..."
}
}
Stop-Transcript
EDIT:
Removing all duplicate code and values would give you even more concise foreach
loop:
foreach ($Computer in $ComputerNames) {
$source = "C:\support\cisco"
$destination = "\\$Computer\c$\support\cisco"
if (Test-Connection $Computer -Quiet -Count 1) {
Write-Output "Computer $Computer is online"
if (-not (Test-path $destination)) {New-Item -Path $destination -ItemType Directory}
robocopy /mir $source $destination
}
else {
Write-Output "Computer $Computer not reachable (PING) - Skipping this computer..."
}
}
Upvotes: 4