<# .SYNOPSIS GDCI Migrations windows bastion automation script .DESCRIPTION Script can check connections to machines, copy automation scripts to machines, and run scripts on remote machines. Targets are in a supplied CSV file. Source directory (where you run this script from) must include: - .\bastion-migration.ps1 (this script) - .\migration-list.csv (list of targets, and relevant needed information) - .\psexec.exe (used for connecting to remote machines and running code/scripts) - .\Server-Side\*.ps1 (scripts to be copied to targets (see $Script_filenames declaration below for expected files)) *** NOTE *** You must run this script with -step paramater set. A list of steps is below. .\bastion-migration.ps1 -Step (Mandatory) - determines which portion of the script to run. Acceptable steps listed below: checkinput - Imports source file and prints to screen the first record of it. used to verify datasources test - Connects to each target to verify connectivity and return local hostname to verify psexec function. checkfiles - Check each target for .\server-side\*.ps1 script location. If not found, places them there. forcefiles - Places or force overwrites each target's .\server-side\*.ps1 script files. 2-4-week - Runs 2-4-week script on target post-migration - Runs post-migration on target -file (Mandatory) - either JSON or CSV file with list of machines to target -AccountShort (Optional) - Add a short accountame (text only, no spaces) for filenames and logging. Default "RACK" -verbosemode (Optional) - Additional logging to output screen Version History: (Original) SEP2020 VMware vcenter commands integrated into multiple scripts to push files to VMs and run ps1 files on VMs -SP -JL (0.9) 13OCT2020 VMWare script updated for new features and bugfixes, combined into 1 script -JT (1.0) 22OCT2020 Converted into psexec and $admin share mapping instead of using vmware commands -JT (1.1) 23OCT2020 Converted to use JSON input as well as original CSV input, added more switches/logging -JT #> Param ( [Parameter(Mandatory=$false,Position=0)][string]$Version = "1.2", # Script version [Parameter(Mandatory=$true,Position=0)][string]$Step, # Which portion of the script to run [Parameter(Mandatory=$true,Position=0)][string]$File, # Source JSON or CSV file to run script from [Parameter(Mandatory=$false,Position=0)][string]$AccountShort, # Account shortname for logging [switch]$VerboseMode # Verbose mode on ) # Save error action state $OriginalErrorActionPreference = $ErrorActionPreference # Set error action state so we don't get any red errors muffing up our output # Error reporting quieting for no gross red text everywhere. if (!$VerboseMode) { $ErrorActionPreference= 'SilentlyContinue' } # -------------------------------------------------------------------------------------------` # BEGIN SCRIPT VARIABLES # -------------------------------------------------------------------------------------------` # SET THIS TO A SHORT ACCOUNT NAME FOR FILENAMES AND OTHER REFERENCES if ($AccountShort -eq $null) {$AccountShort = 'RACK'} # SET THIS LOCATION TO YOUR IMPORT CSV WITH LIST OF TARGET DEVICES # $CSV_Targets = Import-Csv -Path "C:\rs-pkgs\migration-list.csv" if ($File -like '*.json') { $convertedjson = Get-Content -Raw -Path $File | ConvertFrom-Json foreach ($jsonRecord in $convertedjson) { # Convert DNS Source values to string $output = $null;foreach ($a in $jsonRecord.DNSSource){$output += '"' + $a+ '",'};$output = $output.Substring(0,$output.Length-1);$jsonRecord.DNSSource = $output # Convert DNS Migration values to string $output = $null;foreach ($a in $jsonRecord.DNSMigration){$output += '"' + $a+ '",'};$output = $output.Substring(0,$output.Length-1);$jsonRecord.DNSMigration = $output # Convert NTP Migration values to string $output = $null;foreach ($a in $jsonRecord.NTPMigration){$output += '"' + $a+ '",'};$output = $output.Substring(0,$output.Length-1);$jsonRecord.NTPMigration = $output # Convert BackupNetworks to string $output = $null;foreach ($a in $jsonRecord.BackupNetworks){$output += '"' + $a+ '",'};$output = $output.Substring(0,$output.Length-1);$jsonRecord.BackupNetworks = $output } $CSV_Targets = $convertedjson } if ($file -like '*.csv'){$CSV_Targets = Import-Csv -Path $File} # List of expected scripts to exist on targets. these must also exist in .\Server-Side\ folder on the source device you run the script from. $Script_filenames = @('2-Hour.ps1','2-4-Week.Ps1','Shutdown.ps1','Post-Migration.ps1') # -------------------------------------------------------------------------------------------` # END OF SCRIPT VARIABLES # -------------------------------------------------------------------------------------------` # ------------------------------------------------------------------------------------------- # Following function checks a target by name or IP, attemps connection with psexec and returns a string with local hosts's hostname, if found. # ------------------------------------------------------------------------------------------- function Confirm-Connection { param([String]$Name, [String]$IP, [PSCredential]$PSCred) $result = & .\PsExec.exe -accepteula -nobanner -h -u $PSCred.UserName -p $PSCred.GetNetworkCredential().Password \\$IP hostname 2> $null if ($VerboseMode) {& .\PsExec.exe -accepteula -nobanner -h -u $PSCred.UserName -p $PSCred.GetNetworkCredential().Password \\$IP hostname} if ($VerboseMode) {Write-Host "Result from remote host: $($tmpvar)"} # DEBUG return $result } # ------------------------------------------------------------------------------------------- # Following function checks if a file exists on a target and returns true/false # ------------------------------------------------------------------------------------------- function Check-RemotePath { param([String]$Name, [String]$IP, [PSCredential]$PSCred,[String]$Path) $result = & .\PsExec.exe -accepteula -nobanner -h -u $PSCred.UserName -p $PSCred.GetNetworkCredential().Password \\$IP cmd /c "echo . | powershell -command Test-Path $path" 2> $null return $result } # ------------------------------------------------------------------------------------------- # Following function sends a file to a target # ------------------------------------------------------------------------------------------- function Send-RemoteFile { param([String]$Name, [String]$IP, [PSCredential]$PSCred,[PSCredential]$PSMapperCred,[String]$LocalPath,[String]$FileName) # map a temporary drive to target # Attempt without cred once, in case drive was already mapped. New-PSDrive -Name "MigTemp" -PSProvider "FileSystem" -Root "\\$IP\c$" New-PSDrive -Name "MigTemp" -PSProvider "FileSystem" -Root "\\$IP\c$" -Credential $PSMapperCred # Assume failure unless we can prove it's true $result = $False # Reset tmpvar to null (Just in case) $tmpvar = $null # tmpvar used to show successful psdrive mapping. if its null, that means the drive mapping didn't work $tmpvar = dir MigTemp: if ($VerboseMode) {Write-Host "Mapped drive directory listing: $($tmpvar)"} # DEBUG if ($tmpvar -ne $null) { #Touch to create the file and directories if needed if (!(Test-Path("MigTemp:\rs-pkgs\Server-Side\$FileName"))) {New-Item -ItemType File -Path "MigTemp:\rs-pkgs\Server-Side\$FileName" -Force} # Copy the file to target (overwriting) Copy-Item -Path $LocalPath -Destination "MigTemp:\rs-pkgs\Server-Side\$FileName" -Force $result = Test-Path("MigTemp:\rs-pkgs\Server-Side\$FileName") } else {Write-Host -ForegroundColor red "ERROR: Unable to map drive to target! Skipping..."} # Remove the temporary target mapped drive Remove-PSDrive -Name 'MigTemp' if ($VerboseMode) {Write-Host "File copy success: $result"} # DEBUG if ($result){return $true} else {return $false} } # ------------------------------------------------------------------------------------------- # Following function runs a file on a target, returns text blob # ------------------------------------------------------------------------------------------- function Execute-RemoteFile { param([String]$Name, [String]$IP, [PSCredential]$PSCred,[PSCredential]$PSMapperCred,[String]$FileName,[String]$scriptArgs) $path = "c:\rs-pkgs\Server-Side\$FileName" # Test if expected script exists on target $targetScriptExists = & .\PsExec.exe -accepteula -nobanner -h -u $PSCred.UserName -p $PSCred.GetNetworkCredential().Password \\$IP cmd /c "echo . | powershell -command Test-Path $path" 2> $null if ($targetScriptExists -like '*True*') { # Log we found the expected file $resultText = "OK: $path was located on remote system, continuing..." write-host -ForegroundColor green $resultText # Test for PS 2.0 or greater, if not found, error and exit. $targetPSVersion = & .\PsExec.exe -accepteula -nobanner -h -u $PSCred.UserName -p $PSCred.GetNetworkCredential().Password \\$IP cmd /c "echo . | powershell -command (get-host).version.major" 2> $null if ($VerboseMode) {write-host "Target powershell version: $targetPSVersion"} # DEBUG $targetPSVersion = [int]$targetPSVersion if ($targetPSVersion -gt 1) { # Log we found a good version of powershell $tempresultText = "OK: Remote system reported powershell version of ($($targetPSVersion)), attempting to execute..." $resultText += "`n$tempresultText" write-host -ForegroundColor green $tempresultText # map a temporary drive to target # Attempt without cred once, in case drive was already mapped. New-PSDrive -Name "MigTemp" -PSProvider "FileSystem" -Root "\\$IP\c$" New-PSDrive -Name "MigTemp" -PSProvider "FileSystem" -Root "\\$IP\c$" -Credential $PSMapperCred $tmpvar = $null # tmpvar used to show successful psdrive mapping. if its null, that means the drive mapping didn't work $tmpvar = dir MigTemp: if ($VerboseMode) {Write-Host "Mapped drive directory listing: $($tmpvar)"} # DEBUG if ($tmpvar -ne $null) { # Remove any previous wrapper left remove-item -force -Path 'MigTemp:\rs-pkgs\wrapper.ps1' 2> $null remove-item -force -Path '.\wrapper.ps1' # Create a temporary wrapper file New-Item -ItemType File -Path "MigTemp:\rs-pkgs\wrapper.ps1" -Force # build command, due to psexec not liking passed variables in the powershell command for script filepath if ($scriptArgs -ne $null) # If script args were supplied, build the command this way { # Write-Host $scriptArgs # DEBUG $tempCommand = "& c:\rs-pkgs\server-side\$($FileName) $scriptArgs" } else {$tempCommand = "& c:\rs-pkgs\server-side\$($FileName)"} # Otherwise, build a basic command with no arguments if ($VerboseMode) {write-host "Temp Command: $tempCommand"} # DEBUG # Add the command we generated to to target's wrapper file by creating it locally then copying it to target Add-Content -Path '.\wrapper.ps1' -Value $tempCommand Copy-Item -Path ".\wrapper.ps1" -Destination "MigTemp:\rs-pkgs\wrapper.ps1" -Force if ($VerboseMode) {$z = test-path "MigTemp:\rs-pkgs\wrapper.ps1";write-host "MigTemp:\rs-pkgs\wrapper.ps1 exists: $z"} # DEBUG if ($VerboseMode) {$z = get-content 'MigTemp:\rs-pkgs\wrapper.ps1';write-host "Wrapper file contents: $z"} # DEBUG # Execute built command # $remoteWrapperPath = 'c:\rs-pkgs\wrapper.ps1' $invokeTemp = ".\PsExec.exe -accepteula -nobanner -h -u $($PSCred.UserName) -p '$($PSCred.GetNetworkCredential().Password)' \\$IP cmd /c 'echo . | powershell -executionpolicy bypass -noninteractive -file c:\rs-pkgs\wrapper.ps1' 2> `$null" if ($VerboseMode) {write-host "Invoking command: $invokeTemp"} # DEBUG $fullOutputText = Invoke-Expression $invokeTemp if ($VerboseMode) {Write-Host "Invoked command output: $fullOutputText"} # DEBUG } else {Write-Host -ForegroundColor red "ERROR: Unable to map drive to target! Skipping..."} # Remove the wrapper files remove-item -force -Path 'MigTemp:\rs-pkgs\wrapper.ps1' remove-item -force -Path '.\wrapper.ps1' # Remove the temporary target mapped drive Remove-PSDrive -Name "MigTemp" # Error or show success if some result was gathered if ($fullOutputText -ne $null) {$tempresultText = "OK: Some results were gathered from remote host";write-host -ForegroundColor green $tempresultText;$resultText += "`n$tempresultText"} else{$tempresultText = "ERROR: No result was gathered";write-host -ForegroundColor red $tempresultText;$resultText += "`n$tempresultText"} } else {$resultText = "ERROR: Compatible version of powershell could not be found ($($targetPSVersion))! Aborting...";write-host -ForegroundColor red $resultText} } else {$resultText = "ERROR: Could not connect to target, or $($FileName) was not found on target! Aborting...";write-host -ForegroundColor red $resultText} return $resultText,$fullOutputText } # ------------------------------------------------------------------------------------------- # Following function takes a text user/pass and returns a PSCredential object, for use in other functions code # ------------------------------------------------------------------------------------------- function Create-PSCred { [CmdletBinding()] param( [String]$User, [String]$Pass ) # Secure the password string [securestring]$secStringPassword = ConvertTo-SecureString $Pass -AsPlainText -Force # Create a cred object as expected for psexec runs [pscredential]$credObject = New-Object System.Management.Automation.PSCredential ($User, $secStringPassword) # create a second cred object for use by drive mappings if ($user -like '*.\*') {$user = 'localhost\' + $user.Substring($user.IndexOf('.\')+2)} if ($user -notlike '*\*') {$user = 'localhost\' + $user} [pscredential]$credObject2 = New-Object System.Management.Automation.PSCredential ($User, $secStringPassword) if ($VerboseMode){write-host "User $($credobject.username)"; write-host "MapperUser $($credobject2.username)"} if ($credObject -eq $null){write-host -ForegroundColor red "ERROR: PSCredential creation failed"} else {return $credObject,$credObject2} } # Check if the CSV provided was empty or missing, throw an error and exit. if ([string]::isnullorempty($CSV_Targets)){write-host -ForegroundColor Red "ERROR: CSV file provided was not valid! Aborting..."} # Check if PSEXEC exists in the directory, if not error and exit. elseif (!(test-path '.\psexec.exe')){write-host -ForegroundColor Red "ERROR: PSEXEC.EXE was not found in the current directory! Aborting..."} # Main logic for switch detection else{ Write-host -ForegroundColor yellow "Found $($CSV_Targets.length) targets in provided import file..." # Convert step input to common upper case $Step = $Step.ToUpper() # Save a run timestamp for later use by logging $Stamp = (get-date -f yyyyMMdd_HHmmss) + "GMT" + (get-date -f %z) # ------------------------------------------------------------------------------------------- # TEST step will attempt to connet via psexec and poll the target's hostname # ------------------------------------------------------------------------------------------- if ($Step -eq "TEST") { foreach ( $Target in $CSV_Targets ) { $TargetExists = $null # Reset the variable to null at the top of each loop if ($VerboseMode) {write-host "Attempt PScred create with: $($target.username), $($target.password)"} # DEBUG # Create a pscredential object using the supplied text username/password $tempPSCred,$tempPSMapperCred = Create-PSCred -user $Target.username -pass $Target.password if ($VerboseMode) {write-host "PSCRED: $($tempPSCred), PSMAPPERCRED: $($tempPSMapperCred)"} # DEBUG Write-Host -ForegroundColor yellow "Attempting to connect to $($Target.Name) on $($Target.IP)" $result = Confirm-Connection -Name $Target.Name -IP $Target.IP -PSCred $tempPSCred # Check if this target is able to be connected to with psexec if ($result -eq $null) {Write-Host -ForegroundColor red "ERROR: Null result from target";$result = "FAILURE"} Else{Write-Host -ForegroundColor Green "OK: Device at $($Target.IP) returned hostname from local console: $result "} # Log results to text log file locally Add-Content -Path ".\$AccountShort`_Win_$Step`_$Stamp.txt" -Value "$($Target.Name) $($Target.IP)" Add-Content -Path ".\$AccountShort`_Win_$Step`_$Stamp.txt" -Value "Returned local result: $($result)" Add-Content -Path ".\$AccountShort`_Win_$Step`_$Stamp.txt" -Value "-------------------------------------------------------------------------------------------`n" } } # ------------------------------------------------------------------------------------------- # CHECKINPUT step will check and output the first record from the imported file # ------------------------------------------------------------------------------------------- elseif ($Step -eq "CHECKINPUT") { write-output $CSV_Targets[0] } # ------------------------------------------------------------------------------------------- # CHECKFILES checks if files exist on targets and attempts to copy them if not # ------------------------------------------------------------------------------------------- elseif ($Step -eq "CHECKFILES") { foreach ( $Target in $CSV_Targets ) { if ($VerboseMode) {write-host "Attempt: $($target.username), $($target.password)"} # DEBUG # Create a pscredential object using the supplied text username/password $tempPSCred,$tempPSMapperCred = Create-PSCred -user $Target.username -pass $Target.password if ($VerboseMode) {write-host "PSCRED: $($tempPSCred), PSMAPPERCRED: $($tempPSMapperCred)"} # DEBUG Write-Host -ForegroundColor yellow "Attempting to connect to $($Target.Name) on $($Target.IP)" # Start the log header for this target Add-Content -Path ".\$AccountShort`_Win_$Step`_$Stamp.txt" -Value "$($Target.Name) $($Target.IP)" #Check each path, log, plus write result locally # --------------------------------------------------------------------------------- foreach ($tempFileName in $Script_filenames) { $tempFullPath = 'C:\rs-pkgs\Server-Side\' + $tempFileName $result = Check-RemotePath -Name $Target.Name -IP $Target.IP -PSCred $tempPSCred -Path $tempFullPath # write-host $result # DEBUG if ($result -like '*True*') {$resultText = "OK: Path $($tempFullPath) was found on remote system";write-host -ForegroundColor green $resultText} else { # First, log that we did NOT find the file in the correct location $resultText = "ERROR: Path $($tempFullPath) was NOT found on remote system" write-host -ForegroundColor red $resultText Add-Content -Path ".\$AccountShort`_Win_$Step`_$Stamp.txt" -Value $resultText if (test-path ".\Server-Side\$($tempFileName)") { # Log that we will try copying and what we are doing Write-Host -ForegroundColor Yellow "Source $tempFileName.ps1 found, attempting to copy to $($Target.Name) on $($Target.IP)" Add-Content -Path ".\$AccountShort`_Win_$Step`_$Stamp.txt" -Value "Source $tempFileName found, attempting to copy to $($Target.Name) on $($Target.IP)" # Attempt file copy $result = Send-RemoteFile -Name $Target.Name -IP $Target.IP -PSCred $tempPSCred -PSMapperCred $tempPSMapperCred -LocalPath ".\Server-Side\$($tempFileName)" -FileName $tempFileName if ($result -eq $true){Write-Host -ForegroundColor green "OK: Target file found after copy."} else {Write-Host -ForegroundColor red "ERROR: Target file still not found after copy."} $resultText = "File copy success: $result" } else {Write-Host -ForegroundColor red "ERROR: Source file .\Server-Side\$($tempFileName) was not found! Skipping..."; $resultText = "Source $tempFileName not found! Skipping..."} } Add-Content -Path ".\$AccountShort`_Win_$Step`_$Stamp.txt" -Value $resultText # Clear variable for next use $result = $null # --------------------------------------------------------------------------------- } # Write log footer for this target Add-Content -Path ".\$AccountShort`_Win_$Step`_$Stamp.txt" -Value "-------------------------------------------------------------------------------------------`n" } } # ------------------------------------------------------------------------------------------- # FORCEFILES forces overwrite of server-side files on all targets (useful if they are updated during migration prep window) # ------------------------------------------------------------------------------------------- elseif ($Step -eq "FORCEFILES") { foreach ( $Target in $CSV_Targets ) { if ($VerboseMode) {write-host "Attempt: $($target.username), $($target.password)"} # DEBUG # Create a pscredential object using the supplied text username/password $tempPSCred,$tempPSMapperCred = Create-PSCred -user $Target.username -pass $Target.password if ($VerboseMode) {write-host "PSCRED: $($tempPSCred), PSMAPPERCRED: $($tempPSMapperCred)"} # DEBUG Write-Host -ForegroundColor yellow "Attempting to connect to $($Target.Name) on $($Target.IP)" # Start the log header for this target Add-Content -Path ".\$AccountShort`_Win_$Step`_$Stamp.txt" -Value "$($Target.Name) $($Target.IP)" # Send each file # --------------------------------------------------------------------------------- foreach ($tempFileName in $Script_filenames) { $tempFullPath = 'C:\rs-pkgs\Server-Side\' + $tempFileName if (test-path ".\Server-Side\$($tempFileName)") # Check if source file exists locally first { # Clear Variables just in case [bool]$result = $false $resultText = $null # Log that we will try copying and what we are doing Write-Host -ForegroundColor Yellow "Source $tempFileName.ps1 found, attempting to copy to $($Target.Name) on $($Target.IP)" Add-Content -Path ".\$AccountShort`_Win_$Step`_$Stamp.txt" -Value "Source $tempFileName found, attempting to copy to $($Target.Name) on $($Target.IP)" # Attempt file copy $functionresult = Send-RemoteFile -Name $Target.Name -IP $Target.IP -PSCred $tempPSCred -PSMapperCred $tempPSMapperCred -LocalPath ".\Server-Side\$($tempFileName)" -FileName $tempFileName if ($functionresult -like '*True*'){$result=$true} if ($VerboseMode) {write-host $result.gettype();write-host "Result: $result"} # DEBUG if ($result -eq $true){Write-Host -ForegroundColor green "OK: Target file found after copy."} else {Write-Host -ForegroundColor red "ERROR: Target file still not found after copy."} $resultText = "File copy success: $result" Add-Content -Path ".\$AccountShort`_Win_$Step`_$Stamp.txt" -Value $resultText if ($VerboseMode) {write-host $resultText} # DEBUG # Clear variable for next use } else {Write-Host -ForegroundColor red "ERROR: Source file .\Server-Side\$($tempFileName) was not found! Skipping..."; $resultText = "Source $tempFileName not found! Skipping..."} } # --------------------------------------------------------------------------------- # Write log footer for this target Add-Content -Path ".\$AccountShort`_Win_$Step`_$Stamp.txt" -Value "-------------------------------------------------------------------------------------------`n" } } # ------------------------------------------------------------------------------------------- # Following will run each milestone # ------------------------------------------------------------------------------------------- elseif ($Step -eq "POST-MIGRATION") { foreach ( $Target in $CSV_Targets ) { if ($VerboseMode) {write-host "Attempt: $($target.username), $($target.password)"} # DEBUG # Create a pscredential object using the supplied text username/password $tempPSCred,$tempPSMapperCred = Create-PSCred -user $Target.username -pass $Target.password if ($VerboseMode) {write-host "PSCRED: $($tempPSCred), PSMAPPERCRED: $($tempPSMapperCred)"} # DEBUG Write-Host -ForegroundColor yellow "Attempting to connect to $($Target.Name) on $($Target.IP)" # Start the log header for this target Add-Content -Path ".\$AccountShort`_Win_$Step`_$Stamp.txt" -Value "$($Target.Name) $($Target.IP)" $resultText,$fullOutputText = Execute-RemoteFile -Name $Target.Name -IP $Target.IP -PSCred $tempPSCred -PSMapperCred $tempPSMapperCred -FileName 'Post-Migration.ps1' if ($VerboseMode) {Write-Host "ResultText: $resultText"} # DEBUG if ($VerboseMode) {write-host "FullOutputText: $fullOutputText"} # DEBUG Add-Content -Path ".\$AccountShort`_Win_$Step`_$Stamp.txt" -Value $resultText Add-Content -Path ".\$AccountShort`_Win_$Step`_$Stamp.txt" -Value $fullOutputText # Write log footer for this target Add-Content -Path ".\$AccountShort`_Win_$Step`_$Stamp.txt" -Value "-------------------------------------------------------------------------------------------`n" $resultText,$fullOutputText = $null } } elseif ($Step -eq "2-4-WEEK") { foreach ( $Target in $CSV_Targets ) { if ($VerboseMode) {write-host "Attempt: $($target.username), $($target.password)"} # DEBUG # Create a pscredential object using the supplied text username/password $tempPSCred,$tempPSMapperCred = Create-PSCred -user $Target.username -pass $Target.password if ($VerboseMode) {write-host "PSCRED: $($tempPSCred), PSMAPPERCRED: $($tempPSMapperCred)"} # DEBUG Write-Host -ForegroundColor yellow "Attempting to connect to $($Target.Name) on $($Target.IP)" # Start the log header for this target Add-Content -Path ".\$AccountShort`_Win_$Step`_$Stamp.txt" -Value "$($Target.Name) $($Target.IP)" # Generate the args needed for script $tempArgs = "-OldSNIP $($Target.OldSNIP) -OldSNGW $($Target.OldSNGW) -NewSNIP $($Target.NewSNIP) -NewSNGW $($Target.NewSNGW) -NewSNMask $($Target.NewSNMask) -Account $($Target.Account) -DeviceNumber $($Target.DeviceNumber) -DC $($Target.DC) -DpDevice $($Target.DpDevice) -DpAccount $($Target.DpAccount) -DnsSource $($Target.DnsSource) -DnsMigration $($Target.DnsMigration) -NtpMigration $($Target.NtpMigration) -BackupNetworks $($Target.BackupNetworks)" if ($VerboseMode) {write-host "Arguments: $tempargs"} # DEBUG # Attempt to run the remote file with args specified. $resultText,$fullOutputText = Execute-RemoteFile -Name $Target.Name -IP $Target.IP -PSCred $tempPSCred -PSMapperCred $tempPSMapperCred -FileName '2-4-Week.ps1' -scriptArgs $tempArgs if ($VerboseMode) {Write-Host "ResultText: $resultText"} # DEBUG if ($VerboseMode) {write-host "FullOutputText: $fullOutputText"} # DEBUG Add-Content -Path ".\$AccountShort`_Win_$Step`_$Stamp.txt" -Value $resultText Add-Content -Path ".\$AccountShort`_Win_$Step`_$Stamp.txt" -Value $fullOutputText # Write log footer for this target Add-Content -Path ".\$AccountShort`_Win_$Step`_$Stamp.txt" -Value "-------------------------------------------------------------------------------------------`n" $resultText,$fullOutputText = $null } } elseif ($Step -eq "2-HOUR") { foreach ( $Target in $CSV_Targets ) { if ($VerboseMode) {write-host "Attempt: $($target.username), $($target.password)"} # DEBUG # Create a pscredential object using the supplied text username/password $tempPSCred,$tempPSMapperCred = Create-PSCred -user $Target.username -pass $Target.password if ($VerboseMode) {write-host "PSCRED: $($tempPSCred), PSMAPPERCRED: $($tempPSMapperCred)"} # DEBUG Write-Host -ForegroundColor yellow "Attempting to connect to $($Target.Name) on $($Target.IP)" # Start the log header for this target Add-Content -Path ".\$AccountShort`_Win_$Step`_$Stamp.txt" -Value "$($Target.Name) $($Target.IP)" $tempArgs = "-OldSNIP $($Target.OldSNIP) -OldSNGW $($Target.OldSNGW) -NewSNIP $($Target.NewSNIP) -NewSNGW $($Target.NewSNGW) -NewSNMask $($Target.NewSNMask) -Account $($Target.Account) -DeviceNumber $($Target.DeviceNumber) -DC $($Target.DC) -DpDevice $($Target.DpDevice) -DpAccount $($Target.DpAccount) -DnsSource $($Target.DnsSource) -DnsMigration $($Target.DnsMigration) -NtpMigration $($Target.NtpMigration) -BackupNetworks $($Target.BackupNetworks)" if ($VerboseMode) {write-host "Arguments: $tempargs"} # DEBUG # Attempt to run the remote file with args specified. $resultText,$fullOutputText = Execute-RemoteFile -Name $Target.Name -IP $Target.IP -PSCred $tempPSCred -PSMapperCred $tempPSMapperCred -FileName '2-hour.ps1' -scriptArgs $tempArgs if ($VerboseMode) {Write-Host "ResultText: $resultText"} # DEBUG if ($VerboseMode) {write-host "FullOutputText: $fullOutputText"} # DEBUG Add-Content -Path ".\$AccountShort`_Win_$Step`_$Stamp.txt" -Value $resultText Add-Content -Path ".\$AccountShort`_Win_$Step`_$Stamp.txt" -Value $fullOutputText # Write log footer for this target Add-Content -Path ".\$AccountShort`_Win_$Step`_$Stamp.txt" -Value "-------------------------------------------------------------------------------------------`n" $resultText,$fullOutputText = $null } } elseif ($Step -eq "SHUTDOWN") { foreach ( $Target in $CSV_Targets ) { if ($VerboseMode) {write-host "Attempt: $($target.username), $($target.password)"} # DEBUG # Create a pscredential object using the supplied text username/password $tempPSCred,$tempPSMapperCred = Create-PSCred -user $Target.username -pass $Target.password if ($VerboseMode) {write-host "PSCRED: $($tempPSCred), PSMAPPERCRED: $($tempPSMapperCred)"} # DEBUG Write-Host -ForegroundColor yellow "Attempting to connect to $($Target.Name) on $($Target.IP)" # Start the log header for this target Add-Content -Path ".\$AccountShort`_Win_$Step`_$Stamp.txt" -Value "$($Target.Name) $($Target.IP)" # Generate the args needed for script $tempArgs = "-OldSNIP $($Target.OldSNIP) -OldSNGW $($Target.OldSNGW) -NewSNIP $($Target.NewSNIP) -NewSNGW $($Target.NewSNGW) -NewSNMask $($Target.NewSNMask) -Account $($Target.Account) -DeviceNumber $($Target.DeviceNumber) -DC $($Target.DC) -DpDevice $($Target.DpDevice) -DpAccount $($Target.DpAccount) -DnsSource $($Target.DnsSource) -DnsMigration $($Target.DnsMigration) -NtpMigration $($Target.NtpMigration) -BackupNetworks $($Target.BackupNetworks)" if ($VerboseMode) {write-host "Arguments: $tempargs"} # DEBUG # Attempt to run the remote file with args specified. $resultText,$fullOutputText = Execute-RemoteFile -Name $Target.Name -IP $Target.IP -PSCred $tempPSCred -PSMapperCred $tempPSMapperCred -FileName 'Shutdown.ps1' -scriptArgs $tempArgs if ($VerboseMode) {Write-Host "ResultText: $resultText"} # DEBUG if ($VerboseMode) {write-host "FullOutputText: $fullOutputText"} # DEBUG Add-Content -Path ".\$AccountShort`_Win_$Step`_$Stamp.txt" -Value $resultText Add-Content -Path ".\$AccountShort`_Win_$Step`_$Stamp.txt" -Value $fullOutputText # Write log footer for this target Add-Content -Path ".\$AccountShort`_Win_$Step`_$Stamp.txt" -Value "-------------------------------------------------------------------------------------------`n" $resultText,$fullOutputText = $null } } # If an invalid step was provided, error and do nothing else{write-host -ForegroundColor Red "ERROR: No valid step was provided. Use 'get-help' on this script for examples."} } # Return error action to prior value $ErrorActionPreference = $OriginalErrorActionPreference