Powershell remote installed softwares using workflow paralell - powershell

I am trying to convert my inventory script to be able to get a csv list of installed softwares on remote servers using workflows but I am not able to get it.
$tod = Get-Date;
$local = $PSScriptRoot +"\_Output\"+ "$((Get-Date).ToString('yyyyMMdd'))" + "\InstalledSoftwares\";
if(!(Test-Path -Path $local ))
{
New-Item -ItemType Directory -Path $local
}
$ItemList = Import-Csv $($PSScriptRoot + "\_HostList.CFG") -Header Srv -Delimiter ";"
Write-Host $ItemList.srv
workflow AllInstalledSoft {
ForEach -Parallel ($Serv in $ItemList.srv) {
#$Serv = $_.Srv
if (Test-Connection -computer $Serv -count(1) -quiet)
{
InlineScript { Write-Host $using:Serv "Is Reachable" -ForegroundColor Green
$file = $using:Serv+"_InstalledSoft"+"-{0:yyyyMMdd}.csv" -f $tod
$ExportFile = $local+$file
Get-WmiObject -Class Win32_Product -PSComputerName $using:Serv | select-object #{l="HostName";e={$using:Serv}},Name,InstallDate,InstallLocation,Vendor,Version,Caption,LocalPackage,IdentifyingNumber | Export-CSV -path $ExportFile -notypeinformation}
}
else
{
InlineScript { Write-Host $using:Serv "Is UnReachable" -ForegroundColor Red}
}
}
}
AllInstalledSoft

I cannot test but try this and see if it works. Don't try with the full hostname list, just reduce it to 5 computers to test if it works.
EDIT 3 :
$tod = (Get-Date).ToString('yyyyMMdd')
$local = $PSScriptRoot + "\_Output\" + $tod + "\InstalledSoftwares"
if(!(Test-Path -Path $local )){
New-Item -ItemType Directory -Path $local
}
$ItemList = Import-Csv $($PSScriptRoot + "\_HostList.CFG") -Header Srv -Delimiter ";" | Select-Object -Skip 1
workflow AllInstalledSoft {
param (
[parameter(Mandatory=$true)][array]$ItemList,
[parameter(Mandatory=$true)][string]$LocalExport,
[parameter(Mandatory=$true)][string]$Tod
)
ForEach -Parallel ($Serv in $ItemList) {
if(Test-Connection -ComputerName $Serv -Count 1 -Quiet){
$file = "$($Serv)_InstalledSoft-$Tod.csv"
$ExportFile = "$LocalExport\$file"
try {
Get-WmiObject -Class Win32_Product -PSComputerName $Serv -ErrorAction Stop | Select-Object PSComputerName,Name,InstallDate,InstallLocation,Vendor,Version,Caption,LocalPackage,IdentifyingNumber | Export-CSV -Path $ExportFile -NoTypeInformation
}
catch {}
}
}
}
AllInstalledSoft -LocalExport $local -ItemList $ItemList.Srv -Tod $tod

Related

how to use variable out of invoke-command in powershell?

I have below Invoke-command code, the script using hponcfg.exe file on remote server to get ILO configuration. few servers having issue with power capping and error returned by hponcfg.exe as
"Message = 0x0089 Power capping information is not available at this time, try again later."
My question is: I want to capture this error if generated by hponcfg inside invoke-command scriptblock and use it out of scriptblock.
$CurrentDir = (Split-Path $invocation.MyCommand.Path).ToLower()
$CurrentDir
$Credential = get-credential -message "Please supply SA account details."
$servers = gc .\servers.txt
#$Global:ScriptDir = Split-Path $script:MyInvocation.MyCommand.Path
$date = (get-date).ToString("yyyyMMdd_HHmm")
$ILOContent = ".\ILOConfigData_$date.csv"
New-Item -path $ILOContent -type file -Force | out-null
Add-Content -Path $ILOContent -Value "ILO_Name,Model,ILOFIrmware,ILODevice,ILOFWDate,ILO_Domain,Network_Details,ILO_TimeZone,Directory_Users,LDAP_Directory_Authentication,Directory_Groups,SNMP_Settings,Directory_Server_Address"
Foreach($server in $servers){
if (Test-Connection -ComputerName $server -Quiet)
{
#$Frompath = ".\ILO_Prerequisite\"
#$To_Path = "C:\Program Files\Hewlett Packard Enterprise\HPONCFG"
$tmp="Drv_$server"
new-psdrive $tmp filesystem "\\$server\C$" -cred $cred|Out-Null
$Model = (Get-WmiObject -ComputerName $server -Class:Win32_ComputerSystem).model
Write-Host "Validating HPE pre-requisites on server:"$server -BackgroundColor DarkGray -ForegroundColor White
if (-not(test-path("$($tmp):\Program Files\Hewlett Packard Enterprise\HPONCFG")))
{
Write-Host "Corrupt 'HPONCFG' folder structure found. Remediating, will take few seconds." -ForegroundColor Red
New-Item -Path ("$($tmp):\Program Files\Hewlett Packard Enterprise\") -ItemType Directory -Name HPONCFG -Force|Out-Null
$To_Path =("$($tmp):\Program Files\Hewlett Packard Enterprise\HPONCFG")
$From_Path = ".\ILO-PreRequisite\*"
copy-item -path $From_Path -Destination $To_Path -recurse -Force
Sleep(6)
Write-Host "'HPONCFG' folder structure remediated." -ForegroundColor Green
}
Elseif (-not(test-path("$($tmp):\Program Files\Hewlett Packard Enterprise\HPONCFG\hponcfg.exe")))
{
$To_Path =("$($tmp):\Program Files\Hewlett Packard Enterprise\HPONCFG")
Write-Host "Corrupt 'HPONCFG' folder structure found. Remediating, will take few seconds." -ForegroundColor Red
copy-item -path $From_Path -Destination $To_Path -recurse -Force
Sleep(6)
Write-Host "'HPONCFG' folder structure remediated" -ForegroundColor Green
}
remove-psdrive -name $tmp -force
#if (-not(test-path "C:\Program Files\Hewlett Packard Enterprise\HPONCFG\hponcfg.exe"))
# {
# do copy job
# write-host "Copying files and folders from $frompath to $topath" -ForegroundColor Yellow
# copy-item -path $frompath -Destination $topath -recurse
# }
$export = Invoke-Command -ComputerName $server -Credential $Credential -ScriptBlock {
New-Item -Path "C:\Program Files\Hewlett Packard Enterprise\HPONCFG" -ItemType File -Name Current_ILOConfig.xml -Force| Out-Null
Set-Location "C:\Program Files\Hewlett Packard Enterprise\HPONCFG"
$ILODataPath = Get-Location
$WantFile = "$ILODataPath\Current_ILOConfig.txt"
$FileExists = Test-Path $WantFile
If ($FileExists -eq $True) {Remove-Item $WantFile }
Sleep(2)
Write-Host "Gathering current ILO configuration for $ENV:COMPUTERNAME" -ForegroundColor Yellow
& "C:\Program Files\Hewlett Packard Enterprise\HPONCFG\hponcfg.exe" /a /w `
"C:\Program Files\Hewlett Packard Enterprise\HPONCFG\Current_ILOConfig.xml" |Out-Null
Get-Content .\Current_ILOConfig.xml
}
$export|Out-File "Current_ILOConfig.txt"
Sleep(3)
$ILORAW_DATA = Get-Content .\Current_ILOConfig.txt
$ILORAW_DATA|ForEach-Object{
$_ -replace '<!-- ' `
-replace ' -->' `
-replace '<' `
-replace ' />' `
-replace '"' `
}|Set-Content .\Current_ILOConfig.txt
$ILO_DATA = Get-Content .\Current_ILOConfig.txt
Write-Host "Getting ILO DNS details"
$DNS_NAME = $ILO_DATA |Where {$_ |Select-String -Pattern " DNS_NAME VALUE"," DOMAIN_NAME VALUE"}
$ILONAME = $DNS_NAME -split "="
$ILO_Name = $ILONAME[1]
$ILO_Domain = $ILONAME[3]
Write-Host "Getting ILO Network details"
$NT = $ILO_DATA | where {$_ |Select-String -Pattern " IP_ADDRESS VALUE"," SUBNET_MASK"," GATEWAY_IP_ADDRESS"," PRIM_DNS_SERVER VALUE", " SEC_DNS_SERVER VALUE"," TER_DNS_SERVER VALUE" }
$Network = [array]$NT -join "`n"
$Network_Details = $Network.Trim()
Write-Host "Getting ILO TimeZone"
$TZ= $ILO_DATA |Where {$_ | Select-String -Pattern " TIMEZONE VALUE"}
$TimeZone =$TZ -Split "="
$ILO_TimeZone = $TimeZone[1]
Write-Host "Getting ILO Directory Server Address" # Directory_Server_Address
$DSA = $ILO_DATA |Where {$_ | Select-String -Pattern " DIR_SERVER_ADDRESS"}
$DIR_SERVERADDRESS = $DSA -Split "="
$Directory_Server_Address = $DIR_SERVERADDRESS[1]
$ILODeviceID = #()
$ILODev = $ILO_DATA|where{$_|Select-String -Pattern "Device: "}
$ILODevStr = $ILODev -split(' ')
$ILODeviceID += $ILODevStr[1..2] -as [string]
$ILODeviceID += $ILODevStr[7]
$ILODeviceID += $ILODevStr[-1]
Write-Host "Getting LDAP Directory Authentication Enabled/Disabled?"
$LDAP_DIR = $ILO_DATA |Where {$_ | Select-String -Pattern " DIR_AUTHENTICATION_ENABLED"}
$LDAP_DIR_STATUS = $LDAP_DIR -split "="
$LDAP_Directory_Authentication = $LDAP_DIR_STATUS[1]
Write-Host "Getting ILO Device detail"
$ILOFIrmware = $ILODevStr[7]
Write-Host "Getting ILO Firmware Version"
$ILODevice = $ILODevStr[1,2]
Write-Host "Getting ILO Firmware Version date"
$ILOFWDate = $ILODevStr[-1]
Write-Host "Getting SNMP Settings" #SNMP_Settings
$SNMPADDRESS = $ILO_DATA |Where {$_ | Select-String -Pattern "SNMP_ADDRESS"}
$SNMP_DATA = #()
foreach($SNMP in $SNMPADDRESS)
{
$SNMP_DATA +=($SNMP -split "VALUE=")[1]
}
$SNMP_Settings = $SNMP_DATA -join "`n"
Write-Host "Getting ILO Directory User details"
$DIR_USER = $ILO_DATA |Where {$_ | Select-String -Pattern " DIR_USER_CONTEXT"}
$User =#()
foreach($Usr in $DIR_USER)
{
$User += ($Usr -split "VALUE=")[1]
}
#$User
$Directory_Users = $User -join "`n"
#group Account details
Write-Host "Getting ILO Directory Group details"
$DIR_GRPACCT = $ILO_DATA |Where {$_ | Select-String -pattern " DIR_GRPACCT"}
$ACCTs = #()
for($a=1;$a -le 10;$a++)
{
$GroupName = "DIR_GRPACCT" + $a + "_NAME"
#$Privilege = "DIR_GRPACCT" + $a + "_PRIV"
$DIR_GRPACCT = $ILO_DATA |Where {$_ | Select-String -pattern $groupname}
foreach ($acct in $DIR_GRPACCT)
{
$ACCTS += ($acct -split "VALUE=")[1]
}
$DIR_GRPACCTS = ($ACCTS -join "`n")
}
$data = "`"$ILO_Name`",`"$Model`",`"$ILOFIrmware`",`"$ILODevice`",`"$ILOFWDate`",`"$ILO_Domain`",`"$Network_Details`",`"$ILO_TimeZone`",`"$($Directory_Users.trimend())`",`"$LDAP_Directory_Authentication`",`"$($DIR_GRPACCTS.trimend())`",`"$($SNMP_Settings.trimend())`",`"$($Directory_Server_Address.trimend())`""
$Data |Out-File -Append $ILOContent
}
else
{
write-host -ForegroundColor Red "Server $server is not reachable"
$data = "`"$server`",`"not reachable`""
$Data |Out-File -Append $ILOContent
}
}
#Clear User defined variables
Write-Host "Performing Clean-up" -ForegroundColor Yellow
#Clear-Variable -Name ILO*
Function Get-ScriptVariable ($Name = '*')
{
# these variables may exist in certain environments (like ISE, or after use of foreach)
$special = 'ps','psise','psunsupportedconsoleapplications', 'foreach', 'profile'
$ps = [PowerShell]::Create()
$null = $ps.AddScript('$null=$host;Get-Variable')
$reserved = $ps.Invoke() |
Select-Object -ExpandProperty Name
$ps.Runspace.Close()
$ps.Dispose()
Get-Variable -Scope Global |
Where-Object Name -like $Name |
Where-Object { $reserved -notcontains $_.Name } |
Where-Object { $special -notcontains $_.Name } |
Where-Object Name
}Get-ScriptVariable|Out-Null
Get-ScriptVariable |Clear-Variable ;Write-Host "Clean-up completed." -ForegroundColor Green
Write-Host "Check detailed log stored at path: "$CurrentDir -ForegroundColor Green```
You can use try-catch-finally method to get your error messages.
Hi I have modified your script invoke-command part only. Please test and use it. This script is not tested.
$export = Invoke-Command -ComputerName $server -Credential $Credential -ScriptBlock {
try {
New-Item -Path "C:\Program Files\Hewlett Packard Enterprise\HPONCFG" -ItemType File -Name Current_ILOConfig.xml -Force | Out-Null
Set-Location "C:\Program Files\Hewlett Packard Enterprise\HPONCFG"
$ILODataPath = Get-Location
$WantFile = "$ILODataPath\Current_ILOConfig.txt"
$FileExists = Test-Path $WantFile
If ($FileExists -eq $True) { Remove-Item $WantFile }
Sleep(2)
Write-Host "Gathering current ILO configuration for $ENV:COMPUTERNAME" -ForegroundColor Yellow
& "C:\Program Files\Hewlett Packard Enterprise\HPONCFG\hponcfg.exe" /a /w `
"C:\Program Files\Hewlett Packard Enterprise\HPONCFG\Current_ILOConfig.xml" | Out-Null
Get-Content .\Current_ILOConfig.xml
}
catch {
return $_
}
}
$export | Out-File "Current_ILOConfig.txt"

Send variables from inside Invoke-Command scriptblock back to host

The below is a script that is collecting information about SQL-jobs on remote servers.
However, I want to send the information inside the catch-block back to the host.
As the script is written now the script is printing to a logfile on each remote server.
How can I send the information back to the host?
$sqlServers = #("SERVER1","SERVER2")
$runningHost = "$env:computername"
$filePath = "C:\SQLJobInventory"
$desktopPath = [Environment]::GetFolderPath("Desktop")
$output = Invoke-Command -ComputerName $sqlServers -ArgumentList $filePath,$dateToday,$dateTodayFile -ScriptBlock{
param
(
$filePath,
$dateToday,
$dateTodayFile
)
$runningHostRemote = $env:computername
Try
{
Import-Module sqlserver -ErrorAction Stop
$instances = $runningHostRemote | Foreach-Object {Get-ChildItem -Path "SQLSERVER:\SQL\$_"} -ErrorAction Stop
}
Catch
{
Write-Output "$dateToday [ERROR] $runningHostRemote" |
Out-File "$filePath\Log$dateTodayFile.txt" -Append
Exit
}
ForEach ($instance in $instances)
{
Try
{
$instanceName = $instance.InstanceName
Get-SqlAgentJob -ServerInstance "$runningHostRemote\$instanceName" -ErrorAction Stop |
Where-Object {$_.IsEnabled -eq "True" -and $_.LastRunDate -gt [DateTime]::Today.AddDays(-2) -and $_.OwnerLoginName -match "LKL"} |
Select-Object #{Name=‘Job name‘;Expression={$_.Name}},
#{Name=‘Description‘;Expression={$_.Description}},
#{Name=‘Instance‘;Expression={$_.Parent -Replace '[][]'}},
#{Name=‘Run outcome‘;Expression={$_.LastRunOutcome}},
#{Name=‘Run date‘;Expression={$_.LastRunDate}},
#{Name=‘Run duration‘;Expression={$_.LastRunDuration}},
#{Name=‘Job creator‘;Expression={$_.OwnerLoginName}},
#{Name=‘Runs on a schedule‘;Expression={$_.HasSchedule}},
#{Name='Schedule Type';Expression={$_.JobSchedules -join ','}}
}
Catch
{
Write-Output "$dateToday [ERROR] $runningHostRemote\$instanceName" |
Out-File "$filePath\Log$dateTodayFile.txt" -Append
Exit
}
}
}
$output | Select-Object -Property * -ExcludeProperty PSComputerName,RunSpaceID,PSShowComputerName |
Sort-Object "Job name" |
Export-Csv $filePath\SQLJobInvent$dateTodayFile.csv -NoTypeInformation -Delimiter ";" -Encoding UTF8
Write-Output "$dateToday [INFO] $filePath\Log$dateTodayFile.txt" |
Out-File "$filePath\Log$dateTodayFile.txt" -Append
Change write-output to return
Catch
{
Return "$dateToday [ERROR] $runningHostRemote\$instanceName"
}
Return will exit the script block and pass your string back to the output variable.
I have solved it by creating my own properties of the output-variable with New-Object.
There is probably a better way to do it but this was the most convinient.
The Return-method did not work for me in this particular script.
$runningHost = "$env:computername"
$filePath = "C:\SQLJobInventory"
$lastResortPath = [Environment]::GetFolderPath("Desktop")
$dateToday = Get-Date -Format “yyMMdd HH:mm"
$dateTodayFile = Get-Date -Format “yyMMdd"
$output = Invoke-Command -ComputerName $sqlServers -ArgumentList $filePath,$dateToday,$dateTodayFile -ScriptBlock{
param
(
$filePath,
$dateToday,
$dateTodayFile
)
$runningHostRemote = $env:computername
Try
{
Import-Module sqlserver -ErrorAction Stop
$instances = $runningHostRemote | Foreach-Object {Get-ChildItem -Path "SQLSERVER:\SQL\$_"} -ErrorAction Stop
}
Catch
{
$moduleError = #{moduleError="$dateToday [ERROR] $runningHostRemote"}
New-Object -Type PSObject -Property $moduleError
Exit
}
ForEach ($instance in $instances){
Try
{
$instanceName = $instance.InstanceName
$jobSuccess = #{jobSuccess="$dateToday [INFO]"}
New-Object -Type PSObject -Property $jobSuccess
Get-SqlAgentJob -ServerInstance "$runningHostRemote\$instanceName" -ErrorAction Stop |
Where-Object {$_.IsEnabled -eq "True" -and $_.LastRunDate -gt [DateTime]::Today.AddDays(-2) -and $_.OwnerLoginName -match "LKL"} |
Select-Object #{Name=‘Job name‘;Expression={$_.Name}},
#{Name=‘Description‘;Expression={$_.Description}},
#{Name=‘Instance‘;Expression={$_.Parent -Replace '[][]'}},
#{Name=‘Run outcome‘;Expression={$_.LastRunOutcome}},
#{Name=‘Run date‘;Expression={$_.LastRunDate}},
#{Name=‘Run duration‘;Expression={$_.LastRunDuration}},
#{Name=‘Job creator‘;Expression={$_.OwnerLoginName}},
#{Name=‘Runs on a schedule‘;Expression={$_.HasSchedule}},
#{Name='Schedule Type';Expression={$_.JobSchedules -join ','}}
}
Catch
{
$jobError = #{jobError="$dateToday [ERROR] $runningHostRemote\$instanceName"}
New-Object -Type PSObject -Property $jobError
Exit
}
}
}
$output | Select-Object -ExpandProperty moduleError -ErrorAction SilentlyContinue | Out-File "$filePath\Log$dateTodayFile.txt" -Append
$output | Select-Object -ExpandProperty Jobsuccess -ErrorAction SilentlyContinue | Out-File "$filePath\Log$dateTodayFile.txt" -Append
$output | Select-Object -ExpandProperty jobError -ErrorAction SilentlyContinue | Out-File "$filePath\Log$dateTodayFile.txt" -Append
$output | Select-Object -Property * -ExcludeProperty PSComputerName,RunSpaceID,PSShowComputerName |
Sort-Object "Job name" |
Export-Csv $filePath\SQLJobInvent$dateTodayFile.csv -NoTypeInformation -Delimiter ";" -Encoding UTF8
Write-Output "$dateToday [INFO] $filePath\Log$dateTodayFile.txt" |
Out-File "$filePath\Log$dateTodayFile.txt" -Append

Test-connection for remote pcs

I have the following powershell with the aim of collecting a reg value from a list of remote machines, Ive tried using a test-connection to speed up process where devices are not online but the test-connection fails for all....
Here is the script:
clear
$servers = Get-Content -Path C:\ukdeviceswin10.txt
$PatternSID = 'S-1-5-21-\d+-\d+\-\d+\-\d+$'
$ProfileList = ForEach ($server in $servers)
{ if(test-connection $server -quiet -count 1)
{
invoke-command -computername $server {gp 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\*' | Where-Object {$_.PSChildName -match $PatternSID} |
Select #{name="SID";expression={$_.PSChildName}}}}
foreach ($profile in $profilelist) {
$profile = $profile -replace ".$"
$profile = $profile.substring(6,46)
$profile = $profile -replace "[;]"
$profile = $profile -replace "[ ]"
$profiletest = $profile.substring(0,8)
if ($profiletest -eq "S-1-5-21"){
$Reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::Users, "$server")
$profilekey = $profile + "\\SOFTWARE\\Microsoft\\Office\\Outlook\\Addins\\CofenseOutlookReporter.AddinModule"
$RegKey= $Reg.OpenSubKey("$profilekey")
if ($regKey -eq $null){} else {$LoadbehaviourVersion = $RegKey.GetValue("LoadBehaviour")
$results = $server + " " + $profile + " " + $LoadbehaviourVersion | out-file -filepath c:\dell\regresults.txt -Append
}
$RegKey=""
$LoadbehaviourVersion=""
}
}
}

Is it possible to speed up scanning a list of computers for specific service names?

I'm kind of a newbie to PowerShell and I am currently making a simple service monitoring script. Right now I have a list of computer names and a list of service names that I scan for.
I save the scan to a log. I am wondering if there is any way I can speed up my PowerShell code? I'm not sure if I am using the quickest methods for the job.
Are there any known alternatives to this code that would scan services quicker?
$myServices = $PSScriptRoot + "\services.txt" # $PSScriptRoot references current directory
$myServers = $PSScriptRoot + "\servers.txt"
$Log = $PSScriptRoot + "\svclog.csv"
$LogLive = $PSScriptRoot + "\svclogLive.csv"
$serviceList = Get-Content $myServices
Remove-Item -Path $Log
$results = Get-Content $myServers | ForEach-Object {
foreach ($service in $serviceList) {
if ($s=get-service -computer $_ -name $service -ErrorAction SilentlyContinue)
{
$s | select MachineName, ServiceName, Status, StartType
} else {
# "$_ - Service '$service' does not exist."
}
}
}
$results | Export-CSV $Log -notypeinformation
# Create a second current log that Python can read while this script runs
Copy-Item -Path $Log -Destination $LogLive
Use Invoke-command
$serviceList = Get-Content $myServices
#some code
$results = Get-Content $myServers
Invoke-command -ComputerName $results -ScriptBlock {
Param($MyServices)
Get-Service -Name $MyServices | Select-Object -Property ServiceName, Status, StartType
} -ArgumentList $MyServices,$Null | Select-Object -Property ServiceName, Status, StartType,PSComputerName |
Export-Csv -NoTypeInformation -Path $Log
#For getting starttype in Version 2.0
Get-wmiObject -class Win32_Service -Filter "Name='BITS'" | Select-Object -Property Name, State, startMode
You can try capturing all of the target server's services in an array and looking through it rather than calling get-service on every service you are searching for:
$myServices = $PSScriptRoot + "\services.txt" # $PSScriptRoot references current directory
$myServers = $PSScriptRoot + "\servers.txt"
$Log = $PSScriptRoot + "\svclog.csv"
$LogLive = $PSScriptRoot + "\svclogLive.csv"
$serviceList = Get-Content $myServices
Remove-Item -Path $Log
$results = Get-Content $myServers | ForEach-Object {
# All of the services in one grab
$serverServices = #(Get-Service -computer $_ -ErrorAction SilentlyContinue)
if ($serverServices) {
foreach ($service in $serviceList) {
#Note: this inner use of another $_ may confuse PowerShell...
if ($s = ($serverServices | Where {$_.Name -eq $service}))
{
$s | select MachineName, ServiceName, Status, StartType
} else {
# "$_ - Service '$service' does not exist."
}
}
}
}
$results | Export-CSV $Log -notypeinformation
# Create a second current log that Python can read while this script runs
Copy-Item -Path $Log -Destination $LogLive

Powershell Workflow: Using if/else statement?

I am trying to use a workflow in order to make a script run faster by running a ping on several machines in parallel. Where I am getting stuck is trying to use my if/else statement within the workflow and adding log entries based on the results of the ping. Right now, it is not writing anything to the logs based on the ping results. Any assistance would be greatly appreciated. I am open to suggestions for different methods to do this, as long as they do not involve using a module. I want to stick with just Powershell code (I do not have permissions to install modules on the server where this would be running). Thank you! Here is my current code:
<#
.NOTES
===========================================================================
Created on: 10/6/2016 8:06 AM
Created by:
Organization:
Filename: Get-MPOSOfflinePrinters.ps1
===========================================================================
.DESCRIPTION
#>
$logfile = "D:\Logs\MPOSPrinterPingLog.txt"
$offlineprinters = "D:\Reports\MPOS\MPOSOfflinePrinters.txt"
If (Test-Path $logfile) {Remove-Item $logfile}
If (Test-Path $offlineprinters) {Remove-Item $offlineprinters}
Add-Content $logfile "Setting local path"
$localPath = "C:\Temp\MPOS"
Add-Content $logfile "Gathering server list"
$serverList = (Get-ADComputer -Filter "Name -like 'Q0*P30' -or Name -like 'Q0*P32'" -SearchBase "OU=Print,OU=Prod,OU=POS,DC=COMPANY,DC=NET").name | Sort-Object | Out-File C:\Temp\MPOS\MPOSPrintServers.txt
$serverListPath = "C:\Temp\MPOS\MPOSPrintServers.txt"
#Retrieve a list of MPOS Print servers from text file and set to $serverNames
Add-Content $logfile "Compiling text file"
$serverNames = Get-Content -Path $serverListPath
#Iterate through each of the server names
foreach ($serverName in $serverNames) {
Add-Content $logfile "Processing $serverName"
#Check if the server is online before doing the remote command
If (Test-Connection -ComputerName $serverName -Quiet -count 1) {
Add-Content $logfile "$serverName is online"
#copy config file from MPOS print to local server for processing
$timestamp1 = (Get-Date -Format g)
Add-Content $logfile "$timestamp1 - Copying xml file from server to local path"
$configPath = "\\$($serverName)\C$\ProgramData\Microsoft\Point Of Service\Configuration\Configuration.xml"
Copy-Item $configPath $localPath
#process xml file to parse IP addresses for ping
$timestamp2 = (Get-Date -Format g)
Add-Content $logfile "$timestamp2 - Processing xml file from $serverName to parse data to csv"
$xml = [xml](Get-Content C:\Temp\MPOS\Configuration.xml)
$PrinterNames = $xml.selectNodes('//PointOfServiceConfig/ServiceObject/Device') | foreach {New-Object -TypeName psobject -Property #{LogicalName=$_.LogicalName.Name}}
$PrinterIPs = $xml.selectNodes('//PointOfServiceConfig/ServiceObject/Device') | foreach {New-Object -TypeName psobject -Property #{HardwarePath=$_.HardwarePath}}
workflow Test-WFConnection {
param(
[string[]]$PrinterIPs
)
foreach -parallel ($PrinterIP in $PrinterIPs) {
$pingableIP = $PrinterIP.HardwarePath
If (Test-Connection -ComputerName $pingableIP -Quiet -Count 1 -ErrorAction SilentlyContinue) {
$timestamp3 = (Get-Date -Format g)
Add-Content -Path $logfile -Value ("$timestamp3 - $serverName, $pingableIP is online and pingable")
} #If (Test-Connection $pingableIP -Quiet -Count 1 -ErrorAction SilentlyContinue) {
Else {
$timestamp3 = (Get-Date -Format g)
Add-Content -Path $offlineprinters -Value ("$timestamp3 - $serverName, $pingableIP is offline!")
} #Else
} #foreach -parallel ($PrinterIP in $PrinterIPs) {
} #workflow Test-WFConnection {
Test-WFConnection -PSComputerName $PrinterIPs
} #If (Test-Connection -ComputerName $serverName -Quiet -count 1) {
Else {
Add-Content $logfile "$serverName is offline!"
} #Else
} #foreach ($serverName in $serverNames) {