Using Invoke-Command, display which machine responded

Welcome Forums General PowerShell Q&A Using Invoke-Command, display which machine responded

Viewing 8 reply threads
  • Author
    Posts
    • #227833
      Participant
      Topics: 2
      Replies: 8
      Points: 59
      Rank: Member

      On a conference call today and my team was asked to look into why another teams machine BSOD’d since they couldn’t find anything. Found out dump files were off entirely. Got me wanting to check all our servers we monitor (3 months in to job) to find out if any of our servers have dumps disabled.

      I have the below, but I’m wanting to inject which server responded. Any help would be appreciated.

       

      #-------------- To check multiple key values ---------------
      # Change your OU, Path, and Keys as needed
      $Computers = (Get-ADComputer -Filter * -SearchBase "DC=Lombardi,DC=local").Name
      $Path = 'HKLM:\System\CurrentControlSet\Control\CrashControl'
      $Key1 = 'CrashDumpEnabled'
      $Key2 = 'AlwaysKeepMemoryDump'
      $Key3 = 'Overwrite'
      
      # Script/Command to run against each machine found within the given OU
      Foreach ($Computer in $Computers)
      {
      Invoke-Command -ScriptBlock {Get-ItemProperty -path $Path | Format-Table $Key1, $Key2, $Key3}
      }
      
      
      #-------------- To check a single keys value ---------------
      # Change your OU, Path, and Key as needed
      $Computers = (Get-ADComputer -Filter * -SearchBase "DC=Lombardi,DC=Local").Name
      $Path = 'HKLM:\System\CurrentControlSet\Control\CrashControl'
      $Key = 'CrashDumpEnabled'
      
      # Script/Command to run against each machine found within the given OU
      Foreach ($Computer in $Computers)
      {
      Invoke-Command -ScriptBlock {Get-ItemPropertyValue -path $Path -Name $Key}
      }
      • This topic was modified 1 week, 6 days ago by ALombardi01.
      • This topic was modified 1 week, 6 days ago by ALombardi01.
    • #227863
      Participant
      Topics: 3
      Replies: 324
      Points: 1,056
      Helping Hand
      Rank: Community Hero

      By default invoke-command returns property PSComputerName. You have to add parameter -HideComputerName to have it not return it. Now if it isn’t showing in the default output, you can ask for it.

      $results = Invoke-Command -ComputerName 'SomeServer' -ScriptBlock {$PSVersionTable}
      $results | select *
      $results | select pscomputername
      

      Output:

      PSComputerName : SomeServer
      RunspaceId     : 189d3ebd-2f2e-48c3-a495-b0bf652e7f91
      IsReadOnly     : False
      IsFixedSize    : False
      IsSynchronized : False
      Keys           : {PSRemotingProtocolVersion, BuildVersion, PSVersion, PSCompatibleVersions...}
      Values         : {2.3, 10.0.14409.1018, 5.1.14409.1018, 1.0 2.0 3.0 4.0 5.0 5.1.14409.1018...}
      SyncRoot       : System.Object
      Count          : 8
      
      PSComputerName
      --------------
      SomeServer
      

      Hope this helps

    • #227908
      Participant
      Topics: 12
      Replies: 1610
      Points: 2,508
      Helping Hand
      Rank: Community Hero

      Also, just as a side note, you are looping though the computers but not adding a -ComputerName param and it’s invoking the command on the local machine? Next, you may want to look at about_Remote_Variables as you are passing external variables into the scriptblock that is executing remotely. Those setting should be managed by GPO, so you may want to validate those policy settings, OU links and servers are in the correct OU.

      • This reply was modified 1 week, 6 days ago by Rob Simmers.
      • This reply was modified 1 week, 6 days ago by Rob Simmers.
    • #227911
      Participant
      Topics: 2
      Replies: 8
      Points: 59
      Rank: Member

      By default invoke-command returns property PSComputerName. You have to add parameter -HideComputerName to have it not return it. Now if it isn’t showing in the default output, you can ask for it.

      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

      Hope this helps

      I think I may have figured out another option. I had another command I ran to check versions of PowerShell on systems and I threw the $Computer command in there. Originally on this code it didn’t like it. I made it part of it’s own label/result now and it doesn’t complain anymore.

       

      Test Environment Results:

      Input:

      #-------------- To check multiple key values ---------------
      # Change your OU, Path, and Key as needed
      $Computers = (Get-ADComputer -Filter * -SearchBase "DC=Lombardi,DC=Local").Name
      $Path = 'HKLM:\System\CurrentControlSet\Control\CrashControl'
      $Key1 = 'CrashDumpEnabled'
      $Key2 = 'AlwaysKeepMemoryDump'
      $Key3 = 'Overwrite'
      
      # Script/Command to run against each machine found within the given OU
      Foreach ($Computer in $Computers)
      {
      Invoke-Command -ScriptBlock {Get-ItemProperty -path $Path | Format-Table @{Label='Server';e={$Computer}},$Key1, $Key2, $Key3}
      }

       

      Output:

      Server CrashDumpEnabled AlwaysKeepMemoryDump Overwrite
      ------ ---------------- -------------------- ---------
      PS01                  7                    0         0
      
      Server CrashDumpEnabled AlwaysKeepMemoryDump Overwrite
      ------ ---------------- -------------------- ---------
      DC01                  7                    0         0
      
      Server CrashDumpEnabled AlwaysKeepMemoryDump Overwrite
      ------ ---------------- -------------------- ---------
      DB01                  7                    0         0
      
      Server CrashDumpEnabled AlwaysKeepMemoryDump Overwrite
      ------ ---------------- -------------------- ---------
      FS01                  7                    0         0

       

      Using it as Format-List (in lieu of table) returns the following, so it shows good either way I want to utilize the info. I’ll likely stick with a table.

      Server               : PS01
      CrashDumpEnabled     : 7
      AlwaysKeepMemoryDump : 0
      Overwrite            : 0
      
      Server               : DC01
      CrashDumpEnabled     : 7
      AlwaysKeepMemoryDump : 0
      Overwrite            : 0
      
      Server               : DB01
      CrashDumpEnabled     : 7
      AlwaysKeepMemoryDump : 0
      Overwrite            : 0
      
      Server               : FS01
      CrashDumpEnabled     : 7
      AlwaysKeepMemoryDump : 0
      Overwrite            : 0
    • #227920
      Participant
      Topics: 2
      Replies: 8
      Points: 59
      Rank: Member

      Also, just as a side note, you are looping though the computers but not adding a -ComputerName param and it’s invoking the command on the local machine? Next, you may want to look at about_Remote_Variables as you are passing external variables into the scriptblock that is executing remotely. Those setting should be managed by GPO, so you may want to validate those policy settings, OU links and servers are in the correct OU.

       

      Not sure if you are asking me or telling me, sorry. So I am only running the command against the local machine and not against the other computers?

    • #227935
      Participant
      Topics: 12
      Replies: 1610
      Points: 2,508
      Helping Hand
      Rank: Community Hero

      Sorry, that was a statement, not a question. You are executing the same code on your local machine, not the remote machine. Try something like this:

      $Computers = (Get-ADComputer -Filter * -SearchBase "DC=Lombardi,DC=local").Name
      $Path = 'HKLM:\System\CurrentControlSet\Control\CrashControl'
      $Key1 = 'CrashDumpEnabled'
      $Key2 = 'AlwaysKeepMemoryDump'
      $Key3 = 'Overwrite'
      
      # Script/Command to run against each machine found within the given OU
      $results = Foreach ($Computer in $Computers) {
          Invoke-Command -ScriptBlock {Get-ItemProperty -path $using:Path -ComputerName $computer | 
          Select-Object -Property $using:Key1, $using:Key2, $using:Key3}
      }
      
      $results
      
    • #228124
      Participant
      Topics: 2
      Replies: 8
      Points: 59
      Rank: Member

      Sorry, that was a statement, not a question. You are executing the same code on your local machine, not the remote machine. Try something like this:

      $Computers = (Get-ADComputer -Filter * -SearchBase "DC=Lombardi,DC=local").Name
      $Path = 'HKLM:\System\CurrentControlSet\Control\CrashControl'
      $Key1 = 'CrashDumpEnabled'
      $Key2 = 'AlwaysKeepMemoryDump'
      $Key3 = 'Overwrite'
      
      # Script/Command to run against each machine found within the given OU
      $results = Foreach ($Computer in $Computers) {
      Invoke-Command -ScriptBlock {Get-ItemProperty -path $using:Path -ComputerName $computer |
      Select-Object -Property $using:Key1, $using:Key2, $using:Key3}
      }
      
      $results

      It doesn’t seem to like the use of the $Using variable. I’ll need to check it out more.

       

      A Using variable cannot be retrieved. A Using variable can be used only with Invoke-Command, Start-Job, or InlineScript in the 
      script workflow. When it is used with Invoke-Command, the Using variable is valid only if the script block is invoked on a 
      remote computer.
      At line:9 char:34
      + ... criptBlock {Get-ItemProperty -path $using:Path -ComputerName $compute ...
      + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      + CategoryInfo : InvalidOperation: (:) [], RuntimeException
      + FullyQualifiedErrorId : UsingWithoutInvokeCommand

      I figured it out. I pulled the -ComputerName $Computer portion out of the ScriptBlock.

      Input:

      $Computers = (Get-ADComputer -Filter * -SearchBase "DC=Lombardi,DC=local").Name
      $Path = 'HKLM:\System\CurrentControlSet\Control\CrashControl'
      $Key1 = 'CrashDumpEnabled'
      $Key2 = 'AlwaysKeepMemoryDump'
      $Key3 = 'Overwrite'
      
      # Script/Command to run against each machine found within the given OU
      $results = Foreach ($Computer in $Computers) {
      Invoke-Command -ComputerName $computer -ScriptBlock {Get-ItemProperty -path $using:Path | 
      Select-Object -Property $using:Key1, $using:Key2, $using:Key3}
      }
      
      $results

      Output:

      CrashDumpEnabled : 7
      AlwaysKeepMemoryDump : 0
      Overwrite : 0
      PSComputerName : PS01
      RunspaceId : 534c0596-c23c-47b9-b10c-457ab6634bd4
      
      CrashDumpEnabled : 0
      AlwaysKeepMemoryDump : 0
      Overwrite : 1
      PSComputerName : DC01
      RunspaceId : 6b268179-e8c2-48f0-9c6a-23bd4360e8ec
      
      CrashDumpEnabled : 7
      AlwaysKeepMemoryDump : 
      Overwrite : 1
      PSComputerName : DB01
      RunspaceId : 72812eeb-d771-4942-8291-09b0c891fcfc
      
      CrashDumpEnabled : 1
      AlwaysKeepMemoryDump : 0
      Overwrite : 1
      PSComputerName : FS01
      RunspaceId : 6cc158a6-bc79-4c46-91a3-db56a3de04a1

       

      I guess my question would be, what is the major benefit of doing it the way I did versus this?

       

       

      • This reply was modified 1 week, 5 days ago by ALombardi01.
      • This reply was modified 1 week, 5 days ago by ALombardi01.
      • This reply was modified 1 week, 5 days ago by ALombardi01. Reason: Trying to fix this quote dammit
      • This reply was modified 1 week, 5 days ago by ALombardi01.
      • This reply was modified 1 week, 5 days ago by ALombardi01.
    • #228199
      Participant
      Topics: 12
      Replies: 1610
      Points: 2,508
      Helping Hand
      Rank: Community Hero

      I guess my question would be, what is the major benefit of doing it the way I did versus this?

      First, sorry for the incorrect placement of the Computer param, was juggling multiple things. The major benefit is the code works. 🙂 The only reason the code you were running was working was it was local. When you execute the script block, that is all that the remote computer sees, basically:

      Get-ItemProperty -path | Format-Table @{Label='Server';e={$Computer}},,,}
      #or
      Get-ItemProperty -path NULL | Format-Table @{Label='Server';e={$Computer}},NULL, NULL, NULL
      

      This would work:

      $Computers = (Get-ADComputer -Filter * -SearchBase "DC=Lombardi,DC=local").Name
      
      # Script/Command to run against each machine found within the given OU
      $results = Foreach ($Computer in $Computers) {
      Invoke-Command -ComputerName $Computer -ScriptBlock {
          $Path = 'HKLM:\System\CurrentControlSet\Control\CrashControl'
          $Key1 = 'CrashDumpEnabled'
          $Key2 = 'AlwaysKeepMemoryDump'
          $Key3 = 'Overwrite'
      
          Get-ItemProperty -path $using:Path -ComputerName $computer |
          Select-Object -Property $using:Key1, $using:Key2, $using:Key3
      }
      

      $Using basically replaces those variables with values when sending to the remote session, otherwise the remote system has no idea what any of those variables are as they are outside of the script block.

    • #228217
      Participant
      Topics: 2
      Replies: 8
      Points: 59
      Rank: Member

      I guess my question would be, what is the major benefit of doing it the way I did versus this?

      First, sorry for the incorrect placement of the Computer param, was juggling multiple things. The major benefit is the code works. 🙂 The only reason the code you were running was working was it was local. When you execute the script block, that is all that the remote computer sees, basically:

      PowerShell
      4 lines

      <textarea class=”ace_text-input” style=”opacity: 0; height: 18px; width: 6.59781px; left: 44px; top: 0px;” spellcheck=”false” wrap=”off”></textarea>

      1
      2
      3
      4
      Get-ItemProperty path | Format-Table @{Label=‘Server’;e={$Computer}},,,}
      #or
      Get-ItemProperty path NULL | Format-Table @{Label=‘Server’;e={$Computer}},NULL, NULL, NULL
      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

      This would work:

      PowerShell
      14 lines

      <textarea class=”ace_text-input” style=”opacity: 0; height: 18px; width: 6.59781px; left: 51px; top: 0px;” spellcheck=”false” wrap=”off”></textarea>

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      $Computers = (Get-ADComputer Filter * SearchBase “DC=Lombardi,DC=local”).Name
      # Script/Command to run against each machine found within the given OU
      $results = Foreach ($Computer in $Computers) {
      Invoke-Command ComputerName $Computer ScriptBlock {
      $Path = ‘HKLM:\System\CurrentControlSet\Control\CrashControl’
      $Key1 = ‘CrashDumpEnabled’
      $Key2 = ‘AlwaysKeepMemoryDump’
      $Key3 = ‘Overwrite’
      Get-ItemProperty path $using:Path ComputerName $computer |
      Select-Object Property $using:Key1, $using:Key2, $using:Key3
      }
      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

      $Using basically replaces those variables with values when sending to the remote session, otherwise the remote system has no idea what any of those variables are as they are outside of the script block.

      Gotcha. Thanks for clarifying.

Viewing 8 reply threads
  • You must be logged in to reply to this topic.