2017-08-22 1 views
-2

現在、私たちのドメインに参加しているコンピュータのリストを取得し、作成したAccessデータベースに存在するかどうかを確認するために一度に1つずつ繰り返しますWMIクエリを実行してシステム情報を収集し、そのデータがDBに追加されていない場合は追加します。私は正常にコンピュータのほとんど(半分近く)で行うことができますが、彼らのいくつかは、RPCサーバーが見つかりませんでした。Get-WmiObjectがforeachループで正しく機能していない

これらのエラーの一部は、コンピュータがオフラインになっていることが原因であることがわかりました(ファイアウォールは無効で、WMIクエリが有効です)。問題は、一部のコンピュータがオンラインで、スクリプト内でGet-WmiObjectコマンドを実行したときにRPCサーバーエラーが発生することです。ただし、スクリプト外でコマンドを実行すると、情報を正常に照会できます。私は奇妙な振る舞いを引き起こしている機能を掲示しており、プログラミングの知識が豊富な人が私が作り上げている間違いを見つけ出すことを望んでいました。

第2の問題は、最初の反復の後、空白を言うエラーが次のようになるCompNameフィールド?最初の2回の反復は期待どおりに機能し、「コンピュータはすでに存在しています」というエラーが発生します。

Snippet of Error

function Update-Systems { 
    $PSCredential = Get-Credential 
    $Comp = (Get-ADComputer -Filter * | select -ExpandProperty Name) 

    foreach ($Computer in $Comp) { 
     $RecordSet.MoveFirst() 
     $RecordSet.Find("CompName = '$Computer'") 
     $RecordCheck = $RecordSet.Fields.Item("CompName").Value 

     if (!$RecordCheck) { 
      "Collecting Data for $Record" 
      $SystemProp = Get-WmiObject -Class Win32_ComputerSystem -Credential $PSCredential -ComputerName: $Computer -ErrorAction SilentlyContinue 
      $RecordSet.Addnew() 
      $RecordSet.Fields.Item("DateRan") = Get-Date 
      $RecordSet.Fields.Item("Domain") = $SystemProp.Domain 
      $RecordSet.Fields.Item("CompName") = $SystemProp.Name 
      $RecordSet.Fields.Item("Model") = $SystemProp.Model 
      $RecordSet.Fields.Item("Manufacturer") = $SystemProp.Manufacturer 
      $RecordSet.Update() 
     } else { 
      "Computer already exists" 
     } 
    } 
} 
+4

コードの画像は掲載しません。 – TrevorBrooks

+0

あなたの質問をテキストとして含むように質問します。 – LotPings

+1

@TrevorBrooksこれについて申し訳ありませんが、これは私の初めてのStackOverflowへの投稿です。あなたがそれをコピーできない場合、コードはあまり役に立ちません..... – lashing

答えて

0

ほとんどのGet-WmiObjectは、リモートコンピュータから情報を照会することができません。エラー(-ErrorAction SilentlyContinue)の場合にのみ実行するようにコマンドレットに指示してから、エラーが発生すると変数$SystemPropは空になります。そのため、$SystemProp.Name$nullと評価されます。

あなたは、少なくともこのようなフォールバックとして、レコードセットに$Computerではなく$SystemProp.Nameを割り当てることで問題を回避できます。

$RecordSet.Fields.Item("CompName") = if (-not $SystemProp) { 
    $Computer 
} else { 
    $SystemProp.Name 
} 

しかし、より良いアプローチは、適切なエラー処理を行うには、次のようになります。

$ErrorActionPreference = 'Stop' 
try { 
    $SystemProp = Get-WmiObject -Class Win32_ComputerSystem -Credential $PSCredential -ComputerName $Computer 
    $RecordSet.AddNew() 
    $RecordSet.Fields.Item("DateRan")  = Get-Date 
    $RecordSet.Fields.Item("Domain")  = $SystemProp.Domain 
    $RecordSet.Fields.Item("CompName")  = $SystemProp.Name 
    $RecordSet.Fields.Item("Model")  = $SystemProp.Model 
    $RecordSet.Fields.Item("Manufacturer") = $SystemProp.Manufacturer 
} catch { 
    Write-Error $_ -ErrorAction Continue 
} 

また、retryを数回放棄することもできます。

+0

いくつかのテストの後、 'Get-WmiObject'コードを実行する前にいくつかのチェックをしてしまいました。最初のものは '$ RecordSet'に値があるかどうかをチェックします。そうであれば、レコードマーカをデータベースの先頭に移動してコンピュータを見つけようとします。レコードチェックがnullを返した場合は、データをクエリしてDBに追加しようとします。クエリに失敗した場合は、情報を照会できなかったと表示されます。それが情報を取得した場合、それはDBにそれを追加し、次のコンピュータを開始します。あなたの助けをありがとう!これはすべてのエラーを取り除いた:) – lashing

関連する問題