Summary: Learn how to use Windows PowerShell to set security permissions for remoting.

 

Hey, Scripting Guy! QuestionHey, Scripting Guy! I want to use a Windows PowerShell script to set security permissions for Windows PowerShell remoting. Can this be done?

-- LM

 

Hey, Scripting Guy! AnswerHello LM, Microsoft Scripting Guy Ed Wilson here. It rained during the trip to Atlanta. I am not sure, but I think that it rained during the last trip to Atlanta also. The Scripting Wife and I are in Atlanta to attend the Atlanta PowerShell users group. I will be talking about Windows PowerShell best practices as they relate to Windows administration. It was not raining when we entered Georgia, just the part of the trip through the Carolinas. Perhaps the states were afraid we were not coming back; that we would be lured by the excitement of an excellent city such as Atlanta. Unfortunately, a soft housing market will keep us from moving anywhere for the near future. As it is, however, Atlanta is not too far away, and we can enjoy our current neighborhood, plus we can pop over when we are bored with our little berg - or when there is something exciting going on such as a PowerShell users group, or Tech·Ed 2011 (which is already on my calendar May 16 - 19, 2011).

I still had enough status (from my previous travels) with the Microsoft preferred hotel in the area to qualify for a free upgrade to a suite. Therefore, I settled down on the sofa to work on my presentation. The Scripting Wife headed out to the spa. She returned in time for the meeting.

The user group meeting itself was completely full, with standing room only literally (as seen in the following figure).

 

 

I had lots of fun. I was able to see both Hal (aka halr9000) and Jonathan (aka jonwalz) from the PowerScripting pod cast, Aaron (aka SQLvariant) and of course Mark Schill (aka meson3902) who is the Atlanta PowerShell Users Group president. In addition, I made lots of new friends (and even signed a few autographs). To maximize the meeting, we also used Live Meeting and opened it up to the Virtual PowerShell users group, and the New York PowerShell users group. If all this were not enough, the Scripting Wife also made homemade peanut butter fudge.

LM, I wrote the Get-SecurityConfig.ps1 script to enable you to easily use Windows PowerShell to configure custom security settings for remote Windows PowerShell admin. Using this script, you can add specific users and groups and grant them the rights that are required to use Windows PowerShell through remoting to administer a remote computer. The complete Set-SecurityConfig.ps1 script is seen here.

Set-SecurityConfig.ps1

Function Set-SessionConfig

{

 Param( [string]$user )

 $account = New-Object Security.Principal.NTAccount $user

 $sid = $account.Translate([Security.Principal.SecurityIdentifier]).Value

 

 $config = Get-PSSessionConfiguration -Name "Microsoft.PowerShell"

 $existingSDDL = $Config.SecurityDescriptorSDDL

 

 $isContainer = $false

 $isDS = $false

 $SecurityDescriptor = New-Object -TypeName Security.AccessControl.CommonSecurityDescriptor '

   -ArgumentList $isContainer,$isDS, $existingSDDL

 $accessType = "Allow"

 $accessMask = 268435456

 $inheritanceFlags = "none"

 $propagationFlags = "none"

 $SecurityDescriptor.DiscretionaryAcl.AddAccess($accessType,$sid,$accessMask,$inheritanceFlags,$propagationFlags)

 $SecurityDescriptor.GetSddlForm("All")

} #end Set-SessionConfig

 

# *** Entry Point to script ***

 

$user = "nwtraders\poshRemoteUsers"

$newSDDL = Set-SessionConfig -user $user

Get-PSSessionConfiguration |

ForEach-Object {

 Set-PSSessionConfiguration -name $_.name -SecurityDescriptorSddl '

 $newSDDL -force }

 

LM, the first thing to know about the script is that it requires Administrative Credentials. This is because both the Get-PSSessionConfiguration and Set-PSSessionConfiguration Windows PowerShell cmdlets require admin rights. If admin rights are not present when the commands execute an error is generated. The second thing to know about the script is that I based it upon a script that I found in Lee Holmes new book. (My script is completely different from his, but I did get the basic idea from his script and wanted to give him credit. I even decided to use some of his variable names because they made sense).

If the script runs without admin user rights, the error seen in the following figure appears.

 

 

The System.Security.Principal.NTAccount .NET Framework class is used to represent a User Account or a Group. It will work for local usersand domain users. This is a bit confusing. Therefore, let me create an interactive example to illustrate working with a local user. I first use the net user command to list local user accounts. Then I use the NTAccount class to create an object that represents the local user. Next, I call the translate method to retrieve the SID for the local user. This code is shown here, and resembles the code used in the Set-SecurityConfig.ps1 script.

PS C:\> net user

 

User accounts for \\MRED1

 

-------------------------------------------------------------------------------

Administrator            ed                       Guest

The command completed successfully.

 

PS C:\> $user = New-Object security.principal.ntaccount mred1\ed

PS C:\> $user

 

Value

-----

mred1\ed

 

 

PS C:\> $user.Translate([Security.Principal.SecurityIdentifier]).Value

S-1-5-21-348779199-2510906443-2301796693-1001

PS C:\>

 

Next, I have to retrieve the Security Descriptor in SDDL format that is applied to the Windows PowerShell remoting session. It is possible there is more than one Windows PowerShell remoting session configuration - depending on whether the computer is 64 bit or not. However, both Windows PowerShell sessions will probably have the same current security configuration. Therefore, retrieving only one will be fine. This part of the code is seen here.

$config = Get-PSSessionConfiguration -Name "Microsoft.PowerShell"

 $existingSDDL = $Config.SecurityDescriptorSDDL

 

To change the security, I have to use the System.Security.AccessControl.CommonSecurityDescriptor .NET Framework class. The CommonSecurityDescriptor class represents a security descriptor. A security descriptor includes a group, an owner, a Discretionary Access Control List (DACL) and a System Access Control List (SACL). The following code creates a new instance of the CommonSecurityDescriptor class by using security settings I obtained from the Microsoft.PowerShell session configuration.

$isContainer = $false

 $isDS = $false

 $SecurityDescriptor = New-Object -TypeName Security.AccessControl.CommonSecurityDescriptor '

   -ArgumentList $isContainer,$isDS, $existingSDDL

 

Because I have an instance of the CommonSecurityDescriptor class, I can now call the AddAccess method to add my new security setting to the security descriptor. This is seen here.

$accessType = "Allow"

 $accessMask = 268435456

 $inheritanceFlags = "none"

 $propagationFlags = "none"

 $SecurityDescriptor.DiscretionaryAcl.AddAccess($accessType,$sid,$accessMask,$inheritanceFlags,$propagationFlags)

 $SecurityDescriptor.GetSddlForm("All")

 

The entry point to the script specifies the user or group that will be added to the access list. Then it calls the Set-SessionConfig function and stores the new SDDL in a variable called $newSDDL. The script then returns all the Windows PowerShell session configurations that are present on the computer, and pipes those to the ForEach-Object cmdlet. Inside the loop the Set-PssSessionConfiguration cmdlet is used to add the newly created SDDL to Windows PowerShell session configuration. This section of the script is seen here.

$user = "nwtraders\poshRemoteUsers"

$newSDDL = Set-SessionConfig -user $user

Get-PSSessionConfiguration |

ForEach-Object {

 Set-PSSessionConfiguration -name $_.name -SecurityDescriptorSddl '

 $newSDDL -force }

 

When the script runs successfully, the output seen in the following figure appears.

 

 

LM, that is all there is to using Windows PowerShell scripting to configure Windows PowerShell remoting security settings. This also concludes Windows PowerShell remoting week. Join me tomorrow for Quick Hits Friday.

I invite you to follow me on Twitter or Facebook. If you have any questions, send email to me at scripter@microsoft.com or post them on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

 

Ed Wilson, Microsoft Scripting Guy