2016-11-14 7 views
0

マイPowerShellスクリプトが発生します。新しいオブジェクトPSObjectがnull値の式のエラーに

Param([string]$Computers) #Must supply a comma seperated list of servers 
$Threshold = 20 #Only show CPU over this number 
$NoP = 20 #Number of processes to list 
$NoRS = 4 #Number of result sets 
If (! $Computers) { 
    Write-Host "Connection to server failed - please specify a server name." -ForegroundColor Red 
    Break 
} Else { 
    $ComputerList = $Computers -Split " "#,[StringSplitOptions]'RemoveEmptyEntries') 
} 
$Credential = $host.ui.PromptForCredential("Need credentials", "Please enter your user name and password.", "", "NetBiosUserName") 
If (! $Credential) { 
    Write-Host "Authentication failed - please verify your username and password." -ForegroundColor Red 
    Break 
} 
$UserName = $Credential.Username 
$Password = $Credential.GetNetworkCredential().Password 
$CurrentDomain = "LDAP://" + ([ADSI]"").distinguishedName 
$Domain = New-Object System.DirectoryServices.DirectoryEntry($CurrentDomain,$UserName,$Password) 
If ($Domain.Name -eq $null){ 
    Write-Host "Authentication failed - please verify your username and password." -ForegroundColor Red 
    Break 
} 
ForEach ($ComputerName In $ComputerList) { 
    $LoadPercentage = $Processors.LoadPercentage 
    If (!$LoadPercentage) {$LoadPercentage = 0} 
    Write-Host "Server: $ComputerName (CPU load $LoadPercentage%)" -NoNewline 
    $Processors = Get-WmiObject win32_processor -ComputerName $ComputerName -Credential $Credential 
    $i = 1 
    $TopProcess = @() 
    $PercentComplete = 0 
    Do{ 
     $PercentComplete = [Math]::Floor($i/$NoRS*100) 
     Write-Progress -Activity $ComputerName -Status "$PercentComplete% Complete:" -PercentComplete $PercentComplete 
     $ProcessList = gwmi Win32_PerfFormattedData_PerfProc_Process -ComputerName $ComputerName -Credential $Credential | 
      Select IDProcess,Name,PercentProcessorTime | 
      Where {$_.Name -ne "_Total" -and $_.Name -ne "Idle"} | 
      Sort PercentProcessorTime -Descending | 
      Select -First $NoP 
     ForEach ($Process In $ProcessList) { 
      $row = New-Object PSObject -Property @{ 
       Id = $Process.IDProcess 
       Name = $Process.Name 
       User = (gwmi Win32_Process -ComputerName $ComputerName -Credential $Credential | Where {$_.ProcessId -eq $Process.IDProcess}).GetOwner().User 
       CPU = $Process.PercentProcessorTime/$Processors.NumberOfLogicalProcessors -f {P} 
       Description = (gwmi Win32_Process -ComputerName $ComputerName -Credential $Credential | Where {$_.ProcessId -eq $Process.IDProcess}).Description 
      } 
      $TopProcess += $row 
     } 
     $i++ 
    } While ($i -lt $NoRS + 1) 
    Write-Progress -Activity $ComputerName -Completed 
    $Group = $TopProcess | Where {$_.CPU -gt $Threshold} | Group 'ID' | Where Count -eq $NoRS 
    If (!$Group) { 
     Write-Host " has no processes persistently above $Threshold percent CPU usage." 
    } Else { 
     $Processes = @() 
     ForEach ($Groupee In $Group) { 
      $Ungroup = $Groupee | Select -ExpandProperty Group 
      $CPU = 0 
      ForEach ($ugr in $Ungroup) { 
       $CPU += $ugr.CPU 
      } 
      $row = new-object PSObject -Property @{ 
       Id = $Ungroup.Id | Select -First 1 
       Name = $Ungroup.Name | Select -First 1 
       CPU = $CPU/$NoRS 
       User = $Ungroup.User | Select -First 1 
       Description = $Ungroup.Description | Select -First 1 
      } 
      $Processes += $row 
     } 
     $Processes | Format-Table @{Expression={$_.User};Label="User Name";width=25},@{Expression={$_.CPU};Label="CPU";width=5},@{Expression={$_.Id};Label="ID";width=8},@{Expression={$_.Description};Label="Description";width=48} 
    } 
} 

断続的に次のエラーを与える:

あなたがnull値の表現上のメソッドを呼び出すことはできません。 Cで:\ユーザーはJasons1 \ CPUusage.ps1を\:41文字:4

  • $行=新しいオブジェクトPSObject -Property @ {

  • を~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    • CategoryInfo:はInvalidOperation:(:) []、のRuntimeException
    • FullyQualifiedErrorId。 InvokeMethodOnNull

私はそれがループの中で理解できないので、nullのテストがあるので、動作するかスキップする必要があります。

+0

この 'User =(gwmi Win32_Process -ComputerName $ ComputerName ....' 'GetOwner()'の部分です。その時点で一致するプロセスが見つからないことを推測します。 。。。そのためのアカウント – Matt

答えて

2

あなたの問題は、この行から派生していることをかなり確信して:

User = (gwmi Win32_Process -ComputerName $ComputerName -Credential $Credential | Where {$_.ProcessId -eq $Process.IDProcess}).GetOwner().User 

具体的.GetOwner()から。 where句がループ内にある間、その項目の一致するプロセスを見つけてはならない。私は時間が経過していないことが分かっていますが、WMIクエリは最速のものではありません。

先に$ProcessList = gwmi Win32_PerfFormattedData_PerfProc_Processに問い合わせて、その後gwmi Win32_Processを使用しているプロセスが変更された可能性があります。これについても説明する必要があります。時間が経過し、糸が永遠に生きていない。

$queryResult = gwmi Win32_Process -ComputerName $ComputerName -Credential $Credential | Where {$_.ProcessId -eq $Process.IDProcess} 
$owner = if($queryResult){$queryResult.GetOwner().User}else{"Process DNE"} 
#... 

User = $owner 

非常にはっきりしませんが、wmiクエリからのヌルリターンの可能性を説明します。

+0

おかげであなたは上のスポットでした 私はそのライン41を忘れてしまったが、複数行のコマンドだったので、42から47にラインをチェックしませんでした:/ –

+0

OK '$ StillExists = gwmi Win32_Processに-ComputerName $コンピューター - 資格$資格| {。 $所有者= $ StillExists.GetOwner()ユーザー } {。$ _ PROCESSID -eq $ Process.IDProcess} てみ最後に{ ' はを与えます **あなたがnull値の表現上のメソッドを呼び出すことはできません。** ** + $ユーザー= $ StillExists.GetOwner()。ユーザー + ~~~~~~~~~~~~~~~ **** + FullyQualifiedErrorId:InvokeMethodOnNull ** 「試してみる」とエラーが止まると思ったのですが? –

+1

'try'は_terminating errors_のみを停止します。それで、私はテストのために真実の声明を使ったのです。あなたのシナリオでは$ stillexistsはnullです。 – Matt

関連する問題