Home > Sample chapters > Programming > Visual Studio and .NET

Using PowerShell Remoting and Jobs

Using Windows PowerShell remoting: step-by-step exercises

In this exercise, you will practice using Windows PowerShell remoting to run remote commands. For the purpose of this exercise, you can use your local computer. First, you will open the Windows PowerShell console, supply alternate credentials, create a Windows PowerShell remote session, and run various commands. Next, you will create and receive Windows PowerShell jobs.

Supplying alternate credentials for remote Windows PowerShell sessions

  1. Log on to your computer with a user account that does not have administrator rights.

  2. Open the Windows PowerShell console.

  3. Notice the Windows PowerShell console prompt. An example of such a prompt appears here:

    PS C:\Users\ed.IAMMRED>
  4. Use a variable named $cred to store the results of using the Get-Credential cmdlet. Specify administrator credentials to store in the $cred variable. An example of such a command appears here:

    $cred = Get-Credential iammred\administrator
  5. Use the Enter-PSSession cmdlet to open a remote Windows PowerShell console session. Use the credentials stored in the $cred variable, and use localhost as the name of the remote computer. Such a command appears here:

    Enter-PSSession -ComputerName localhost -Credential $cred
  6. Notice how the Windows PowerShell console prompt changes to include the name of the remote computer, and also changes the working directory. Such a changed prompt appears here:

    [localhost]: PS C:\Users\administrator\Documents>
  7. Use the whoami command to verify the current context. The results of the command appear here:

    [localhost]: PS C:\Users\administrator\Documents> whoami
    iammred\administrator
  8. Use the exit command to exit the remote session. Use the whoami command to verify that the user context has changed.

  9. Use WMI to retrieve the BIOS information on the local computer. Use the alternate credentials stored in the $cred variable. This command appears here:

    gwmi -Class win32_bios -cn localhost -Credential $cred

    The previous command fails and produces the following error. This error comes from WMI and states that you are not permitted to use alternate credentials for a local WMI connection.

    gwmi : User credentials cannot be used for local connections
    At line:1 char:1
    + gwmi -Class win32_bios -cn localhost -Credential $cred
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : InvalidOperation: (:) [Get-WmiObject], ManagementException
        + FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.
       GetWmiObjectCommand
  10. Put the WMI command into the -scriptblock parameter for Invoke-Command. Specify the local computer as the value for computername and use the credentials stored in the $cred variable. The command appears here (using -script as a shortened version of -scriptblock):

    Invoke-Command -cn localhost -script {gwmi -Class win32_bios} -cred $cred
  11. Press the up arrow key to retrieve the previous command and erase the credential parameter. The revised command appears here:

    Invoke-Command -cn localhost -script {gwmi -Class win32_bios}

    When you run the command, it generates the error appearing here because a normal user does not have remote access by default (if you have admin rights, then the command works):

    [localhost] Connecting to remote server localhost failed with the following error
    
    message : Access is denied. For more information, see the about_Remote_Troubleshooting
    
    Help topic.
    
        + CategoryInfo          : OpenError: (localhost:String) [], PSRemotingTransport
    
       Exception
    
        + FullyQualifiedErrorId : AccessDenied,PSSessionStateBroken
  12. Create an array of computer names. Store the computer names in a variable named $cn. Use the array appearing here:

    $cn = $env:COMPUTERNAME,"localhost","127.0.0.1"
  13. Use Invoke-Command to run the WMI command against all three computers at once. The command appears here:

    Invoke-Command -cn $cn -script {gwmi -Class win32_bios}

    This concludes this step-by-step exercise.

In the following exercise, you will create and receive Windows PowerShell jobs.

Creating and receiving jobs

  1. Open the Windows PowerShell console as a non-elevated user.

  2. Start a job named Get-Process that uses a -scriptblock parameter that calls the Get-Process cmdlet (gps is an alias for Get-Process). The command appears here:

    Start-Job -Name gps -ScriptBlock {gps}
  3. Examine the output from starting the job. It lists the name, state, and other information about the job. Sample output appears here:

    Id     Name            PSJobTypeName   State         HasMoreData     Location
    --     ----            -------------   -----         -----------     --------
    9      gps             BackgroundJob   Running       True            localhost
  4. Use the Get-Process cmdlet to determine if the job has completed. The command appears here:

    Get-Job gps
  5. Examine the output from the previous command. The state reports completed when the job has completed. If data is available, the hasmoredata property reports true. Sample output appears here:

    Id     Name            PSJobTypeName   State         HasMoreData     Location
    --     ----            -------------   -----         -----------     --------
    9      gps             BackgroundJob   Completed     True            localhost
  6. Receive the results from the job. To do this, use the Receive-Job cmdlet as shown here:

    Receive-Job gps
  7. Press the up arrow key to retrieve the Get-Job command. Run it. Note that the hasmoredata property now reports false, as shown here:

    Id     Name            PSJobTypeName   State         HasMoreData     Location
    --     ----            -------------   -----         -----------     --------
    9      gps             BackgroundJob   Completed     False           localhost
  8. Create a new job with the same name as the previous job: gps. This time, change the -scriptblock parameter value to gsv (the alias for Get-Service). The command appears here:

    Start-Job -Name gps -ScriptBlock {gsv}
  9. Now use the Get-Job cmdlet to retrieve the job with the name gps. Note that the command retrieves both jobs, as shown here:

    Get-Job -name gps
    Id     Name            PSJobTypeName   State         HasMoreData     Location
    --     ----            -------------   -----         -----------     --------
    9      gps             BackgroundJob   Completed     False           localhost
    11     gps             BackgroundJob   Completed     True            localhost
  10. Use the Receive-Job cmdlet to retrieve the job ID associated with your new job. This time, use the -keep switch, as shown here:

    Receive-Job -Id 11 -keep
  11. Use the Get-Job cmdlet to retrieve your job. Note that the hasmoredata property still reports true because you’re using the -keep switch.

    This concludes this exercise.