
close
close
During my recent PowerShell workshop in Finland, an attendee asked about Active Directory cmdlets from Microsoft in regards to remote desktop user settings. Although you can readily see the settings in Active Directory Users and Computers, Get-ADUser doesn’t retrieve them. I haven’t worked with Remote Desktop Services in quite a while, but I told him I’d look into this long-standing problem.
Let’s look at the problem. In Active Directory Users and Computers, you might have a setting like this:
Active Directory Users and Computers settings. (Image Credit: Jeff Hicks)
Get-ADUser jdemo –properties *
But you don’t. However, if you happen to be using the ActiveRoles cmdlets from Dell (formerly part of Quest Software), then you can easily get these settings.
Using the ActiveRoles cmdlets from Dell. (Image Credit: Jeff Hicks)
The UserParameters property. (Image Credit: Jeff Hicks)
advertisment
[ADSI]$user = "LDAP://CN=John Demo,OU=Development,DC=Globomantics,DC=Local"
Creating an ADSI object for the user account. (Image Credit: Jeff Hicks)
Retrieving the terminal services properties. (Image Credit: Jeff Hicks)
$user.terminalServicesHomeDirectory = "Y:\RDS"
$user.setinfo()
As you can imagine, this would be a lot of work to do manually, so I wrote a function to get remote desktop settings from the ADUC tab that I’ve been showing you.
Function Get-RDUserSetting { [cmdletbinding(DefaultParameterSetName="SAM")] Param( [Parameter(Position=0,Mandatory,HelpMessage="Enter a user's sAMAccountName", ValueFromPipeline,ParameterSetName="SAM")] [ValidateNotNullorEmpty()] [Alias("Name")] [string]$SAMAccountname, [Parameter(ParameterSetName="SAM")] [string]$SearchRoot, [Parameter(Mandatory,HelpMessage="Enter a user's distingished name", ValueFromPipelineByPropertyName,ParameterSetName="DN")] [ValidateNotNullorEmpty()] [Alias("DN")] [string]$DistinguishedName, [string]$Server ) Begin { Write-Verbose "Starting $($MyInvocation.MyCommand)" Write-Verbose ($PSBoundParameters | Out-String) #remote desktop properties $TSSettings = @("TerminalServicesProfilePath","TerminalServicesHomeDirectory","TerminalServicesHomeDrive") } #Begin Process { Write-Verbose "Using parameter set $($PSCmdlet.ParameterSetName)" Switch ($PSCmdlet.ParameterSetName) { "SAM" { Write-Verbose "Retrieving distinguishedname for $samAccountname" $searcher = New-Object DirectoryServices.DirectorySearcher $searcher.Filter = "(&(objectcategory=person)(objectclass=user)(samAccountname=$sAMAccountname))" Write-Verbose $searcher.filter if ($SearchRoot) { Write-Verbose "Searching from $SearchRoot" if ($Server) { $searchPath = "LDAP://$server/$SearchRoot" } else { $searchPath = "LDAP://$SearchRoot" } $r = New-Object System.DirectoryServices.DirectoryEntry $SearchPath $searcher.SearchRoot = $r } $user = $searcher.FindOne().GetDirectoryEntry() } "DN" { Write-Verbose "Processing $DistinguishedName" if ($server) { Write-Verbose "Connecting to $Server" [ADSI]$User = "LDAP://$Server/$DistinguishedName" } else { [ADSI]$User = "LDAP://$DistinguishedName" } } } #close Switch if ($user.path) { #initialize a hashtable Try { $hash=[ordered]@{ DistinguishedName = $User.DistinguishedName.Value Name = $user.name.Value samAccountName = $user.samAccountName.value AllowLogon = $user.psbase.InvokeGet("AllowLogon") -as [Boolean] } foreach ($property in $TSSettings) { $hash.Add($property,$user.psbase.invokeGet($property)) } #foreach #create an object New-Object -TypeName PSObject -Property $hash } Catch { Write-Warning "Failed to retrieve remote desktop settings for $Distinguishedname. $($_.exception.message)" } } #if user found else { Write-Warning "Failed to find user $DistinguishedName. $($_.exception.message)" } } #Process End { Write-Verbose "Ending $($MyInvocation.MyCommand)" } #End } #end function
To use the command, you can either specify a samaccountname or a distinguishedname. I wrote it so that you could use it in conjunction with Get-ADUser.
Using the Get-rDUserSetting function in Windows PowerShell. (Image Credit: Jeff Hicks)
get-aduser -filter "Name -like 'demouser10*'" | get-rdusersetting | where {-Not $_.AllowLogon}
Using our function in the pipeline. (Image Credit: Jeff Hicks)
advertisment
Function Set-RDUserSetting { [cmdletbinding(SupportsShouldProcess)] Param( [Parameter(Position=0,Mandatory,HelpMessage="Enter a user's sAMAccountName", ValueFromPipeline,ParameterSetName="SAM")] [ValidateNotNullorEmpty()] [Alias("Name")] [string]$SAMAccountname, [Parameter(ParameterSetName="SAM")] [string]$SearchRoot, [Parameter(Mandatory,HelpMessage="Enter a user's distingished name", ValueFromPipelineByPropertyName,ParameterSetName="DN")] [ValidateNotNullorEmpty()] [Alias("DN")] [string]$DistinguishedName, [boolean]$AllowLogon, [Alias("Profile")] [string]$TerminalServicesProfilePath, [Alias("HomeDirectory")] [string]$TerminalServicesHomeDirectory, [Alias("HomeDrive")] [string]$TerminalServicesHomeDrive, [string]$Server, [switch]$Passthru ) Begin { Write-Verbose "Starting $($MyInvocation.MyCommand)" Write-Verbose ($PSBoundParameters | out-string) #remote desktop properties $TSSettings = @("TerminalServicesProfilePath","TerminalServicesHomeDirectory","TerminalServicesHomeDrive") } #Begin Process { Write-Verbose "Using parameter set $($PSCmdlet.ParameterSetName)" Switch ($PSCmdlet.ParameterSetName) { "SAM" { Write-Verbose "Retrieving distinguishedname for $samAccountname" $searcher = New-Object DirectoryServices.DirectorySearcher $searcher.Filter = "(&(objectcategory=person)(objectclass=user)(samAccountname=$sAMAccountname))" Write-Verbose $searcher.filter if ($SearchRoot) { Write-Verbose "Searching from $SearchRoot" if ($Server) { $searchPath = "LDAP://$server/$SearchRoot" } else { $searchPath = "LDAP://$SearchRoot" } $r = New-Object System.DirectoryServices.DirectoryEntry $SearchPath $searcher.SearchRoot = $r } $user = $searcher.FindOne().GetDirectoryEntry() } "DN" { Write-Verbose "Processing $DistinguishedName" if ($server) { Write-Verbose "Connecting to $Server" [ADSI]$User = "LDAP://$Server/$DistinguishedName" } else { [ADSI]$User = "LDAP://$DistinguishedName" } } } #close Switch if ($user.path) { if ($PSBoundParameters.ContainsKey("AllowLogon")) { Write-Verbose "Configuring AllowLogon" $user.psbase.invokeSet("AllowLogon",$AllowLogon -as [int]) } foreach ($property in $TSSettings) { if ($PSBoundParameters.ContainsKey($property)) { Write-Verbose "Setting $property = $($PSBoundParameters[$property])" $user.psbase.invokeSet($property,$PSBoundParameters[$property]) } } #commit changes if ($PSCmdlet.ShouldProcess($DistinguishedName)){ $user.setInfo() } #Whatif if ($Passthru) { $hash=[ordered]@{ DistinguishedName = $User.DistinguishedName.Value Name = $user.name.Value samAccountName = $user.samAccountName.value AllowLogon = $user.psbase.InvokeGet("AllowLogon") -as [Boolean] } foreach ($property in $TSSettings) { $hash.Add($property,$user.psbase.InvokeGet($property)) } #foreach #create an object New-Object -TypeName PSObject -Property $hash } } #if user found else { Write-Warning "Failed to find user $DistinguishedName" } } #Process End { Write-Verbose "Ending $($MyInvocation.MyCommand)" } #End } #end function
Normally I’m not a big fan of parameters that take Boolean values, but it was the simplest solution in this case. Now I can easily set remote desktop settings for multiple user accounts.
Get-ADUser -filter "Name -like 'demouser20*'" |
Set-RDUserSetting -AllowLogon $True -TerminalServicesProfilePath "\\CHI-RDS01\Profiles\$($_.samaccountname)" -TerminalServicesHomeDirectory "Y:\RDS" -Passthru
You might also need to configure settings from the Sessions tab. Those settings can be set the same way. You can either modify my functions or write your own. The property names are:
The time settings are in minutes.
I would recommend putting these functions into a module. This is definitely something you will want to test in a non-production setting.
More from Jeff Hicks
advertisment
Petri Newsletters
Whether it’s Security or Cloud Computing, we have the know-how for you. Sign up for our newsletters here.
advertisment
More in PowerShell
Microsoft’s New PowerShell Crescendo Tool Facilitates Native Command-Line Wraps
Mar 21, 2022 | Rabia Noureen
Most popular on petri
Log in to save content to your profile.
Article saved!
Access saved content from your profile page. View Saved
Join The Conversation
Create a free account today to participate in forum conversations, comment on posts and more.
Copyright ©2019 BWW Media Group