Почему я получаю другой вывод в Powershell от start-job и просто от запуска кода? - PullRequest
1 голос
/ 02 ноября 2019

Скрипт работает правильно, когда за пределами Start-Job, но в блоке скрипта я получаю неверные результатыГде я ошибаюсь?

Мне нужна функциональность Start-Job, так как у меня есть серверы, на которых будут зависать удаленные команды (отдельная проблема - WMI не работает), и мне нужно тайм-аут и перейти на следующий сервер.

Я перепробовал все варианты, которые я могу найти в Google, и до сих пор не могу найти результаты, которые я ищу.

Я действительно схожу с ума с этим, поскольку я непонять, что происходит ... Помощь?

Спасибо!

$timeoutSeconds = 90

ForEach($server in $servers) {
    #$ErrorActionPreference = "inquire"
    #$WarningPreference = "inquire"

    $ErrorActionPreference = "silentlycontinue"
    $WarningPreference = "silentlycontinue"

    write-host $SERVER

    $code = {
        param($SERVER,$LOGto,$outputPath)

        $ping = (Test-Connection -ComputerName $SERVER -Count 2 -Quiet )
        if($ping -eq $true)
        {
            $pingVerbose = (Test-Connection -ComputerName $SERVER -Count 1)
            $IP = $pingVerbose.IPV4Address.IPAddressToString

            $osname2 = (Get-WMIObject -computerName $SERVER win32_operatingsystem).name
            if($osname2 -match "|") 
            {
                $osname,$osname1 = $osname2.Split('|')
            } else {
                $osname = $osname2
            }

            $lastinstalled = (Get-HotFix -computerName $SERVER | where -property InstalledOn -ne $null)
            if($lastinstalled.InstalledOn)
            {
                $lastinstalledOn1 = ($lastinstalled.InstalledOn | Sort-Object -Property InstalledOn )[-1]
                $lastinstalledOn = $lastinstalledOn1
            }

            $lastQFE = (get-wmiobject -class win32_quickfixengineering -computerName $SERVER | where -property InstalledOn -ne $null)
            if($lastQFE.InstalledOn -ne $null)
            {
                $lastQFEon = ($lastQFE.InstalledOn | Sort-Object -Property InstalledOn)[-1]
                $lastQFEon = $lastQFEon
            }

            if(($lastinstalledOn) -or ($lastQFEon))
            {
                if(($lastinstalledOn) -and ($lastinstalledOn -gt $lastQFEon)) 
                {
                    $installedOn = $lastinstalledOn.tostring("MM/dd/yyyy")
                    $HotFixNumber = ($lastinstalled.HotFixID | Sort-Object -Property HotFixID)[-1]
                } else {
                    $installedOn = $lastQFEon.tostring("MM/dd/yyyy")
                    $HotFixNumber = ($lastQFE.HotFixID | Sort-Object -Property HotFixID)[-1]
                }
            } else {
                $installedOn = ''
                $HotFixNumber = ''
            }
        }

    #add entries to the log file
    ac $outputPath\$LOGto "$Server,$ip,$installedOn,$HotFixNumber,$ping,$osname "
    Write-Host "$Server,$ip,$installedOn,$HotFixNumber,$ping,$osname "

    }

    $runCode = Start-Job -ScriptBlock $code -ArgumentList $server,$LOGto,$outputPath

    if(Wait-Job $runCode -Timeout $timeoutSeconds) 
    {
        Receive-Job $runCode
    } else {
        Remove-Job -Force $runCode
        ac $($outputPath + "\error.txt")  "$Server"
    }
}

При запуске в блоке скриптов я получаю неправильную дату и КБ.

SERVERNAME
SERVERNAME,10.1.XX.XX,03/13/2015,KB3022777,True,Microsoft Windows Server 2012 R2 Standard 

vs.

SERVERNAME
SERVERNAME,10.1.XX.XX,05/15/2017,KB4012213,True,Microsoft Windows Server 2012 R2 Standard

1 Ответ

0 голосов
/ 04 ноября 2019

Для потомков больше всего на свете ...

Ошибка, которую я делал, заключалась в использовании объекта сортировки для строки вместо числового значения.

Один из приведенных ниже кодов будет работать правильно один развы заменяете имя домена и информацию о пути к файлу.

Спасибо, Люк

#change this to a directory of your choice
$outputPath = "C:\Users\username\Desktop"
cd $outputPath

#create a default file name
$LOGto = "AllWinHotFixDateDC_$((Get-Date).ToString('yyyyMMdd')).csv"

#create the headers
sc .\$LOGto "Server,IPAddress,InstalledOn,HotFixNumber,Ping,OS_Name"

#get the server names from AD
Get-ADComputer -Filter {(Enabled -eq "True") -and (OperatingSystem -like "*Windows*") } -SearchBase "OU=Servers,DC=mydomain,DC=net" -server 'mydomain.net' -SearchScope Subtree | Select Name -ExpandProperty name |  Sort-Object | Out-File .\servers.txt
$servers = get-content .\servers.txt

$timeoutSeconds = 90

ForEach($server in $servers) {
    $ErrorActionPreference = "inquire"
    $WarningPreference = "inquire"

    #$ErrorActionPreference = "silentlycontinue"
    #$WarningPreference = "silentlycontinue"

    write-host $SERVER

    $code = {
        param($SERVER,$LOGto,$outputPath)

        $ping = (Test-Connection -ComputerName $SERVER -Count 2 -Quiet )
        if($ping -eq $true)
        {
            $pingVerbose = (Test-Connection -ComputerName $SERVER -Count 1)
            $IP = $pingVerbose.IPV4Address.IPAddressToString

            $osname2 = (Get-WMIObject -computerName $SERVER win32_operatingsystem).name
            if($osname2 -match "|") 
            {
                $osname,$osname1 = $osname2.Split('|')
            } else {
                $osname = $osname2
            }

            $getinstalled = (Get-HotFix -computerName $SERVER)
            if($getinstalled)
            {
                if($getinstalled.HotFixID -ne $null)
                {
                    $validinstalled = ($getinstalled.HotFixID -match "KB*")
                    $KB = (($validinstalled -replace 'KB','') | Sort-Object {[int]($_ -replace '(\d+).*', '$1')})[-1]
                    $lastinstalledOnHotFix = ("KB$KB")
                }
                if ($getinstalled.InstalledOn -ne $null)
                {
                    $lastInstalled = ($getinstalled | Sort-Object -Property InstalledOn)[-1] 
                    $lastInstalledlist = $lastInstalled.InstalledOn  | Sort-Object {[int]($_ -replace '(\d+).*', '$1')}
                    $lastInstalledon = $lastInstalledlist.tostring("MM/dd/yyyy")
                } else {
                    $lastinstalledOn = "0"
                }
            }

            Write-Host $lastinstalledOn
            Write-Host $lastinstalledOnHotFix

            $getQFE = (get-wmiobject -class win32_quickfixengineering -computerName $SERVER )
            if($getQFE)
            {
                if($getQFE.HotFixID -ne $null)
                {
                    $validQFE = ($getQFE.HotFixID -match 'KB')
                    $KB = (($validQFE -replace 'KB','') | Sort-Object {[int]($_ -replace '(\d+).*', '$1')})[-1]
                    $lastQFEonHotFix = ("KB$KB")
                }
                if($getQFE.InstalledOn -ne $null)
                {
                    $lastQFE = ($getQFE | Sort-Object -Property InstalledOn)[-1] 
                    $lastQFElist = $lastQFE.InstalledOn  | Sort-Object {[int]($_ -replace '(\d+).*', '$1')}
                    $lastQFEon = $lastQFElist.tostring("MM/dd/yyyy")
                } else {
                    $lastQFEon = "0"
                }

            }

            Write-Host $lastQFEon
            Write-Host $lastQFEonHotFix

            if(($lastinstalledOn -ne $null) -or ($lastQFEon -ne $null))
            {
                if(($lastInstalledlist -ne $null) -and ($lastInstalledlist -gt $lastQFElist)) 
                {
                    $installedOn = $lastinstalledOn
                    $HotFixNumber = $lastinstalledOnHotFix
                } elseif($lastQFEon -ne $null)
                {
                    $installedOn = $lastQFEon
                    $HotFixNumber = $lastQFEonHotFix
                }
            } else {
                $installedOn = '0'
                $HotFixNumber = $lastQFEonHotFix
            }
        }

    #add entries to the log file
    ac $outputPath\$LOGto "$Server,$ip,$installedOn,$HotFixNumber,$ping,$osname "
    Write-Host "$Server,$ip,$installedOn,$HotFixNumber,$ping,$osname "

    }

    $runCode = Start-Job -ScriptBlock $code -ArgumentList $server,$LOGto,$outputPath

    if(Wait-Job $runCode -Timeout $timeoutSeconds) 
    {
        Receive-Job $runCode
    } else {
        Remove-Job -Force $runCode
        ac $($outputPath + "\error.txt")  "$Server"
    }
}


...