Answer the question
In order to leave comments, you need to log in
How to work with Start-Job in Power Shell?
In the written script:
[xml]$inputs = New-Object system.Xml.XmlDocument
$inputs.Load('.\inputs.xml')
[string]$result = ''
[string]$adresses = ''
foreach ($server in $inputs.SelectNodes('//server'))
{
$hostname = $server.host # получаем DNS имя сервера
Start-Job { # стартуем задание
if (Test-Connection $hostname -Quiet)
{
$result += "Ping to " + $hostname + " success`r`n" # формируем содержимое файла report.txt
$port = $server.port
$sock = new-object System.Net.Sockets.Socket -ArgumentList $([System.Net.Sockets.AddressFamily]::InterNetwork),$([System.Net.Sockets.SocketType]::Stream),$([System.Net.Sockets.ProtocolType]::Tcp)
try {
$sock.Connect($hostname,$Port) | Out-Null # попытка соединения
$result += "port " + $port + " connect success`r`n"
$result += "`r`n"
$sock.Close()
}
catch {
$result += "port " + $port + " connect fail`r`n"
$result += "`r`n"
}
}
else
{
$result += "Ping to " + $hostname + " fail`r`n" # формируем содержимое файла report.txt
}
} # конец задания
}
$result += "`r`n"
foreach ($process in $inputs.SelectNodes('//process')) # определяет какие процессы запущены
{
if (Get-Process -Name $process.InnerText -ErrorAction SilentlyContinue)
{
$result += "Process " + $process.InnerText + " exists`r`n"
}
else
{
$result += "Process " + $process.InnerText + " not exists`r`n"
}
}
$result += "`r`n"
foreach ($service in $inputs.SelectNodes('//service'))
{
if (Get-service -Name $service.InnerText -ErrorAction SilentlyContinue)
{ #
$Servicestatus = Get-service $service.InnerText | select status, DisplayName # получение списка служб в Powershell
$result += "Service " + $service.InnerText + " " + $Servicestatus.status + "`r`n"
}
else
{
$result += "Service " + $service.InnerText + " " + "not exists`r`n"
}
}
Start-Sleep -Sec 99 # задержка чтобы пинги отработали
Out-File -FilePath .\report.txt -InputObject $result -Encoding Default
foreach ($adress in $inputs.SelectNodes('//email'))
{
$adresses += $adress.InnerText + "; "
}
if ($adresses -ne '')
{
Add-Type -AssemblyName Microsoft.Office.Interop.Outlook # ошибка если нет Outlook на компе
$Outlook = New-Object -ComObject Outlook.Application
$Mail = $Outlook.CreateItem(0)
$Mail.To = $adresses
$Computer = Get-WmiObject -Class win32_ComputerSystem
$Mail.Subject = "Testing report on "+ $Computer.Name
$Mail.Body =$result
$Mail.Send()
}
Answer the question
In order to leave comments, you need to log in
Managed to solve it like this:
[xml]$inputs = New-Object system.Xml.XmlDocument
$inputs.Load('.\inputs.xml')
[string]$result = ''
[string]$adresses = ''
$matrix = New-Object System.Collections.ArrayList
$Get_Ping={ # функция будет выполняться в задании
param($server)
$hostname = $server.host
if (Test-Connection $hostname -Quiet -count 1){
$resPing += "Ping to " + $hostname + " success`r`n" # формируем содержимое файла report.txt
$port = $server.port
$sock = new-object System.Net.Sockets.Socket -ArgumentList (
$([System.Net.Sockets.AddressFamily]::InterNetwork),
$([System.Net.Sockets.SocketType]::Stream),
$([System.Net.Sockets.ProtocolType]::Tcp) )
try {
$sock.Connect($hostname,$Port) | Out-Null # попытка соединения
$resPing += "Port " + $port + " connect success`r`n`r`n"
$sock.Close()
}
catch {
$resPing += "Port " + $port + " connect fail`r`n`r`n"
}
}
else {
$resPing += "Ping to " + $hostname + " fail`r`n" # формируем содержимое файла report.txt
}
return $resPing
}
foreach ($server in $inputs.SelectNodes('//server'))
{
$jb = Start-Job $Get_Ping -Args $server # запускаем задание для каждого хоста
$matrix.Add($jb)
}
foreach ($process in $inputs.SelectNodes('//process')) # определяет какие процессы запущены
{
if (Get-Process -Name $process.InnerText -ErrorAction SilentlyContinue)
{
$result += "Process " + $process.InnerText + " exists`r`n"
}
else
{
$result += "Process " + $process.InnerText + " not exists`r`n"
}
}
$result += "`r`n"
foreach ($service in $inputs.SelectNodes('//service'))
{
if (Get-service -Name $service.InnerText -ErrorAction SilentlyContinue)
{ #
$Servicestatus = Get-service $service.InnerText | select status, DisplayName # получение списка служб в Powershell
$result += "Service " + $service.InnerText + " " + $Servicestatus.status + "`r`n"
}
else
{
$result += "Service " + $service.InnerText + " " + "not exists`r`n"
}
}
$result += "`r`n"
foreach($jb in $matrix) # собираем результаты выполнения пингов
{
$rez = $jb|Wait-Job|Receive-Job
$result += $rez
}
Out-File -FilePath .\report.txt -InputObject $result -Encoding Default
foreach ($adress in $inputs.SelectNodes('//email'))
{
$adresses += $adress.InnerText + "; "
}
if ($adresses -ne '')
{
Add-Type -AssemblyName Microsoft.Office.Interop.Outlook
$Outlook = New-Object -ComObject Outlook.Application
$Mail = $Outlook.CreateItem(0)
$Mail.To = $adresses
$Computer = Get-WmiObject -Class win32_ComputerSystem
$Mail.Subject = "Testing report on "+ $Computer.Name
$Mail.Body =$result
$Mail.Send()
}
firstly, there is no Wait-Job anywhere
; secondly, the Job itself cannot write anything to the result, you just need to give everything to the output
; thirdly, external variables cannot be used inside the job script - they are not available there, you must pass everything through arguments or $ using:
fourthly, what is issued in output, after wait-job, you need to receive it through receive-job
fifthly, it is better to send mail via Send-MailMessage
finally, sixthly, instead of Job, it is better to use ThreadJob or PoshRSJob - they load the computer less
, that is, the scheme is something like this:
$sourcedata = get-content in_file
$jobs =
foreach ($data in $sourcedata) {
Start-Job { somescript $using:data }
}
$result = $jobs | wait-Job | receive-Job
$jobs | remove-Job
$result | set-content out_file
send-mailmessage ...
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question