Tag Archives: Out-GridView

Invoke a Command from a Get-History Menu

Sometimes you line up the right cmdlets, appreciate what you’ve done for a moment, only to become mildly irritated that you never thought of that before. I just did that.

We all know, or should rather, that the Get-History cmdlet returns a list of commands that have been entered during the current Windows PowerShell session. If you open up a new console, enter a couple commands, and then run Get-History, or one of its aliases (ghy, h, history), it’ll show you what commands you’ve entered up until that point. Take this example, for instance:

PS> Get-Process | Select-Object -Last 2

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    263      11     1680       5132    46     0.02   3356 WUDFHost
    227      12     1824       6804    47     0.22   3840 WUDFHost


PS> Get-Service | Select-Object -First 2

Status   Name               DisplayName
------   ----               -----------
Running  AdobeARMservice    Adobe Acrobat Update Service
Stopped  AdobeFlashPlaye... Adobe Flash Player Update Service


PS> Get-History

  Id CommandLine
  -- -----------
   1 Get-Process | Select-Object -Last 2
   2 Get-Service | Select-Object -First 2


PS> Get-History

  Id CommandLine
  -- -----------
   1 Get-Process | Select-Object -Last 2
   2 Get-Service | Select-Object -First 2
   3 Get-History

I use the up arrow quite often to cycle through my previous commands, and press Enter when I’ve found the one I want to run again. That’s one way to rerun a previously run command. Another, is to use the Get-History cmdlet. First, you use it to determine the ID of the command you want to rerun, such as we’ve done above. Then, you can run Get-History again with the -Id parameter and pipe that result to Invoke-History (aliases: ihy, r), such as we’ve done below. You can also just use Invoke-History -Id 1 without the use of Get-History.

PS> Get-History -Id 1 | Invoke-History
Get-Process | Select-Object -Last 2

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    263      11     1680       5132    46     0.02   3356 WUDFHost
    227      12     1824       6804    47     0.22   3840 WUDFHost

What about making a “menu,” where we can select the command we want to run and press OK to run it? Easy. If you’ve been paying attention to PowerShell, then you’ve probably seen the Out-GridView cmdlet before. Let’s put it to good use, and I’ll show you the cmdlets I lined up.

PS> Get-History | Out-GridView -PassThru | Invoke-History

When I enter the command above, it will show the dialog box below; however, your dialog box will be the default size. I’ve resized mine so that the image better fits on this page. If it’s important to you, you can change what the title says by including Out-GridView’s -Title parameter: Get-History | Out-GridView -PassThru -Title ‘History Menu’ | Invoke-History.

Invoke-a-Command-from-Get-History-Menu01

After I select an option from the list, and press OK, the history item will be rerun.

PS> Get-History | Out-GridView -PassThru | Invoke-History
Get-Process | Select-Object -Last 2

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    263      11     1680       5132    46     0.02   3356 WUDFHost
    227      12     1824       6804    47     0.22   3840 WUDFHost

PS>

Well, there it is. Something so simple and so obvious that I can’t believe I never thought of it before.

Out-GridView in a PSRemoting Session

Twitter Reply to:

We can’t use the Out-GridView cmdlet in a remote session. How do we know this? Well for one, the documentation says so (search for ‘You cannot use a remote command’ on that webpage), and two, because if you try, you’ll get a straight forward error message on the topic: “Out-GridView does not work in a remote session.” Okay, but why?

Out-GridView produces a Graphic User Interface (GUI) — something we don’t use in PSRemoting sessions. In fact, everything about a PSRemoting session is text only. This isn’t just about Out-GridView, though. Other graphical elements in Windows PowerShell aren’t going to work either. This includes Get-Help’s -ShowWindow parameter, and the Show-Command cmdlet. It just wasn’t designed to work this way.

Other GUI elements don’t work either. While you won’t get a helpful message, like you do with the PowerShell cmdlets and parameters, launching notepad.exe and calc.exe isn’t going to work like it does on a local computer. Those programs work a little differently though, as they will actually launch on the remote computer. It just won’t be in any useable fashion from your remote session. Bonus: They may lock up your remote session until they are closed.

Note: If you were to try this, one way to rectify the situation would be to open a second PowerShell console and run the following, assuming you launched calc.exe: Invoke-Command -ComputerName computername -ScriptBlock {Get-Process -Name calc.exe | Stop-Process}. This would end the process on the remote computer, and give you back your prompt on the console where you were running your PSRemoting session.

Everything until now, assumed we were talking about an interactive PSRemoting session (using the Enter-PSSession cmdlet). Well, what about Invoke-Command? Invoke-Command is used to run commands on remote systems and return the results to the local computer. As you can see in the examples below, we can run a command on a remote computer and then display the results on our local computer, inside Out-GridView.

Note: Although I didn’t have any problems with the small handful of cmdlets I tried, the same webpage linked above indicates that data returned from a remote computer may not be formatted correctly for use with Out-GridView.

PS C:\> $Services = Invoke-Command -ComputerName dc01 -ScriptBlock {Get-Service}
PS C:\> $Services | Out-GridView
PS C:\> $PSWARules = Invoke-Command -ComputerName PSWAServer01 -ScriptBlock {Get-PSWAAuthorizationRule}
PS C:\> $PSWARules | Out-GridView

Thanks for the inspiration to write a little about this topic, Tim.