Tag Archives: MimbolovePowershell Remoting

Few PowerShell One-Liners To Check WinRM Settings on Remote Machines

Written by Tao Yang

To Check if WinRM has been enabled on a Remote machine:

$RemoteMachine = “Remote Machine Name”

[system.convert]::ToBoolean(((winrm get winrm/config/winrs -r:$remotemachine | ?{$_ -imatch "AllowRemoteShellAccess"}).split("="))[1].trim())

To Check the Default HTTP listener port on a remote machine:

$RemoteMachine = “Remote Machine Name”

[System.Convert]:: ToInt32(((winrm get winrm/config/Service/DefaultPorts -r:$RemoteMachine | ?{$_ -imatch "HTTP = " }).split("="))[1].trim())

To Check the Default HTTPS listener port on a remote machine:

$RemoteMachine = “Remote Machine Name”

[System.Convert]:: ToInt32(((winrm get winrm/config/Service/DefaultPorts -r:$RemoteMachine | ?{$_ -imatch "HTTPS = " }).split("="))[1].trim())

image

My First Impression on PowerShell Web Access

Written by Tao Yang

I ran up an instance of Windows Server 2012 in my test lab last night so I can play with various new features such as IPAM and PowerShell Web Access, etc.

Today I configured this box as the PowerShell Web Access (PSWA) gateway. I have to say, I am very very impressed! The implementation is easy, took me less than an hour (including time spent reading TechNet articles) and having ability to access PowerShell console on virtually any web browser for all Windows machines in my lab is just fantastic!

Now I can probably get away from using RDP most of the times since I’m pretty comfortable with PowerShell Smile

So, here are the steps I took to setup PSWA:

1. Add the PSWA feature in Server Manager

2. Install PSWA web application using PowerShell:

Install-PswaWebApplication

3. Requested and installed a SSL certificate for the PSWA gateway machine from my Enterprise CA

4. In IIS, configured HTTPS for the default web site and used the SSL certificate I just installed from previous step.

5. Created an AD group called PSWA_Users and added few user IDs into this group.

6. Create PSWA Authorization Rule:

Add-PSWAAuthorizationRule -UserGroupName Corp\PSWA_Users -Computername * -ConfigurationName *

image

7. Since I can’t guarantee that WinRM has been enabled and configured on every machine, I’ve created a GPO to enable WinRM and linked it to the domain root.

Now, PSWA is pretty much ready to go. I launch the web access console on Google Chrome and entered my credential and the computer that I wish to connect to:

image

And I’m in!

image

It’s great to see that Microsoft releases a web-based product that runs on browsers other than IE. I don’t think I’ve seen anything like this before!

Additional Configurations:

I started testing by connecting to a SCOM management server and tried to retrieve all SCOM agents in my management group (Only 11 in total so I’d assume not huge amount of data is returned). I used:

Import-Module OperationsManager

$a = Get-SCOMAgent

Interestingly, it failed and the connection to the management server was closed:

image

Error:

Processing data for a remote command failed with the following error message: The WSMan provider host process did not return a proper response. A provider in the host process may have behaved improperly.

This reminded me the default setting for “Maximum amount of memory in MB per Shell” for WinRM, which I blogged previously in this post. The default setting on Windows Server 2008 R2 and Windows 7 is 150MB. This default setting has increased to 1024MB on Windows Server 2012 and Windows 8.

So to test, since I have 3 management servers in the OM12 management group, I’ve increased this setting to 1024 on another management server. It fixed the error:

image

To further prove this error is actually caused by not having enough memory for the remote shell, I’ve connected PSWA to a Windows 8 machine, which has OM12 console and command shell installed. I used the following commands to connect to the OM12 management group:

Import-Module OperationsManager

New-SCManagementGroupConnection OpsMgrMS03

It prompted an error saying I don’t have sufficient permission:

image

This is by design, when using second hop in CredSSP, the credential has to be explicitly specified. so I changed the command to:

New-SCManagementGroupConnection OpsMgrMS03 –Credential (Get-Credential domain\MyID)

after entering the password, I was successfully connected and I managed to retrieve all SCOM agents by using Get-SCOMAgent Cmdlet without issues.

image

So to fix this issue once for all, I’ve modified the GPO I’ve just created and changed the “Maximum amount of memory in MB per Shell” setting to 1024.

Click here to see settings defined in my WinRM GPO.

I also configured another port forwarding rule on my ADSL router to forward port 443 to the PSWA gateway computer so I can connect when I’m not home.

PSWA on Mobile Devices:

I am able to launch and use PSWA on both my Android tablet (Samsung Galaxy Tab 10.1v running ICS) and my wife’s iPad 3 (running iOS 6) using both built-in browsers and Google Chrome on both devices.

Below are few screenshots from my Galaxy Tab:

image

image

Maybe it’s just me being an Apple noob, when I’m on the iPad, I could not find the Tab key on the keyboard, so I couldn’t use the PowerShell auto completion feature. – One more reason that I’m staying away from that product!

Console Size:

by default, the console size is 120×35, which seems like a waste of space when I’m on a big screen.

So I wrote a simple PowerShell script called Resize-Console.ps1 to resize the window:

$bufferSize = $Host.UI.RawUI.BufferSize
$buffersize.Width = 180
$host.UI.RawUI.BufferSize = $buffersize

$WindowSize = $host.UI.RawUI.WindowSize
$WindowSize.Width = 180
$WindowSize.Height = 40
$host.UI.RawUI.WindowSize = $WindowSize

After I ran this script, the console fits perfectly on my Galaxy tab (resolution 1280×800):

image

This console size also works great on my laptop, which has the resolution of 1366×768. For different resolutions, the width and height need to be adjusted in the script. the only catch is the buffersize cannot be less than the window size (I set the width for both sizes to be the same).

I haven’t managed to work out a automated way to resize the console as when in a PS remote session, there is no $profile so I can’t add scripts into $profile like we normally do on a local console. If I find a way in the future, I’ll post it here.

This is what I found so far. I’ll continue to blog on this topic if I find any other interesting stuff!

By the way, I followed this TechNet article to configure the PSWA: Deploy Windows PowerShell Web Access

Using PowerShell Remote Sessions in a large SCOM environment

Written by Tao Yang

I have previously blogged using SCOM PowerShell snap-in and SDK client in a PowerShell remote session to avoid maintain a consistent SDK connection to RMS server.

I just found out there might be a potential issue when using this technique to run scripts against a reasonably large SCOM management group.

By default, the maximum amount of memory a PowerShell remote session can use is limited to 150MB. You can check this setting on your computer by using

winrm get winrm/config

image

Depending on how much data the remote session has to process, you might running into problems.

For example, compare these 2 scripts:

Sample #1:

$me = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name

$RunAsCred = get-Credential ""

$RMS = ""

$AlertID = "8a5e738c-53d5-4a04-91af-cb8bc2d2e5d3"

$NewSession = new-pssession -ComputerName $env:COMPUTERNAME -Authentication Credssp -Credential (Get-Credential $me)

$alert = invoke-command  -session $NewSession -ScriptBlock {

param($RMS,$AlertID,$RunAsCred)

Add-PSSnapin Microsoft.EnterpriseManagement.OperationsManager.Client

New-PSDrive -Name:Monitoring -PSProvider:OperationsManagerMonitoring -Root:\

Set-Location "OperationsManagerMonitoring::"

new-managementGroupConnection -ConnectionString:$RMS -credential $RunAsCred | Out-Null

Set-Location $RMS

$Alert = Get-Alert | Where-Object {$_.Id -imatch $AlertID}

$Alert

} -ArgumentList $RMS, $AlertID, $RunAsCred

Remove-PSSession $NewSession

$alert

Sample #2:

$me = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name

$RunAsCred = get-Credential ""

$RMS =  ""

$AlertID = "8a5e738c-53d5-4a04-91af-cb8bc2d2e5d3"

$NewSession = new-pssession -ComputerName $env:COMPUTERNAME -Authentication Credssp -Credential (Get-Credential $me)

$alert = invoke-command  -session $NewSession -ScriptBlock {

param($RMS,$AlertID,$RunAsCred)

Add-PSSnapin Microsoft.EnterpriseManagement.OperationsManager.Client

New-PSDrive -Name:Monitoring -PSProvider:OperationsManagerMonitoring -Root:\

Set-Location "OperationsManagerMonitoring::"

new-managementGroupConnection -ConnectionString:$RMS -credential $RunAsCred | Out-Null

Set-Location $RMS

$Alert = Get-Alert -Id $AlertID

$Alert

} -ArgumentList $RMS, $AlertID, $RunAsCred

Remove-PSSession $NewSession

$alert

The difference between these 2 scripts is, when using Get-Alert cmdlet,  #1 uses client side filtering and #2 uses server side filtering:

#1: $Alert = Get-Alert | Where-Object {$_.Id -imatch $AlertID}

#2: $Alert = Get-Alert -Id $AlertID

The management group my scripts connect to has just over 22,000 alerts still in the operational database. So when script #1 runs, because it uses client side filtering, it retrieves all 22,000+ alerts to the local remote session, Then filter out all the rest and retrieves ONE alert with that particular Alert ID. On the other hand, script #2 uses server side filtering, only ONE alert is returned from SCOM RMS server.

Here’s what happened when I tried to run both scripts:

#1:

image

#2:

image

As you can see, script #2 worked as expected but script #1 throws an exception:

Processing data for a remote command failed with the following error message: The WSMan provider host process did not return a proper response.  A provider in the host process may have behaved improperly. For more information, see the about_Remote_Troubleshooting Help topic.

    + CategoryInfo          : OperationStopped: (System.Manageme…pressionSyncJob:PSInvokeExpressionSyncJob) [], PSRemotingTransportException

    + FullyQualifiedErrorId : JobFailure

So now we know that we should use server side filtering because it is more efficient and there are less data returned.  However, not all SCOM cmdlets supports server side filtering. this statement is also true when talking about PowerShell cmdlets in general. not all cmdlets supports server side filtering. Sometimes, I have to use client side filering. For example, when working with Get-agent cmdlet, I have to use client side filtering.

Below script is very similar to script #1, I’ve changed a little bit to retrieve information of a particular SCOM agent:

$me = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name

$RunAsCred = get-Credential ""

$RMS = ""

$AgentName = ""

$NewSession = new-pssession -ComputerName $env:COMPUTERNAME -Authentication Credssp -Credential (Get-Credential $me)

$agent = invoke-command  -session $NewSession -ScriptBlock {

param($RMS,$AgentName,$RunAsCred)

Add-PSSnapin Microsoft.EnterpriseManagement.OperationsManager.Client

New-PSDrive -Name:Monitoring -PSProvider:OperationsManagerMonitoring -Root:\

Set-Location "OperationsManagerMonitoring::"

new-managementGroupConnection -ConnectionString:$RMS -credential $RunAsCred | Out-Null

Set-Location $RMS

$Agent = Get-Agent | Where-Object {$_.PrincipalName -imatch $AgentName}

$Agent

} -ArgumentList $RMS, $AgentName, $RunAsCred

Remove-PSSession $NewSession

$agent

The management group I have connected to has around 5000 agents at the moment, so it’s a reasonable size. Below is what happened:

image

PowerShell threw an exception:

Processing data for a remote command failed with the following error message: <f:WSManFault xmlns:f=”http://schemas.microsoft.com/wbem/wsman/1/wsmanfault” Code=”3762507597″ Machine=”computername”><f:Message><f:ProviderFault provider=”microsoft.powershell” path=”C:\Windows\system32\pwrshplugin.dll”></f:ProviderFault></f:Message></f:WSManFault> For more information, see the about_Remote_Troubleshooting Help topic.

    + CategoryInfo          : OperationStopped: (System.Manageme…pressionSyncJob:PSInvokeExpressionSyncJob) [], PSRemotingTransportException

    + FullyQualifiedErrorId : JobFailure

To make the script run, I had to increase the maximum allowed memory for PowerShell Remote session. In this case, I increased from 150MB to 512MB. I used this command to increase it:

winrm set winrm/config/winrs <code>@</code>{MaxMemoryPerShellMB=<code>&quot;512</code>&quot;`}

After the increase, my get-agent script ran successfully:

Conclusion:

When writing a script, we normally test it against a development or test environment. generally speaking, these environments are much much small than production environments. scripts may run perfectly in dev / test environments but because of the size of environments, we may run into situations like this. Depending on the size of the production environments, we will have to adjust the “MaxMemoryPerShellMB” setting for PowerShell remote sessions accordingly.