Sintez.Module.RDS.psm1
function Install-SintezRDSModuleServer { <# .Synopsis Add/Remove settings for RDS module on server side. .Description Add/Remove user/group to RDP-Tcp administrator group settings on server side (ONLY RDSH servers). This script MUST be started as local Administrator. .Parameter Domain -Domain [-D] - Domain name. For domain.com it should be just DOMAIN. .Parameter Group -Group [-G] - Group of users who allow to connect (shadow) to the user session. .Parameter Remove -Remove [-R] - Clear all custom groups in RDP security settings (reset param). .Parameter View -View [-V] - Show all groups from RDP security settings tab. .Parameter RDSH -RDSH [-SH] - Remote host .Parameter Cred -Cred [-C] - Credentials switch. Enforce credential form. .Example # Add RDS security group with administrator rights (Shadow, Logoff, Disconnect and etc.): Install-SintezRDSModuleServer -Domain DOMAIN -Group rds_support_team .Example # Clear all custom groups in RDP security settings: Install-SintezRDSModuleServer -R .Example # Clear all custom groups in RDP security settings (Remotely): Install-SintezRDSModuleServer -R -H RDSH1,RDSH2,RDSH3 -C .Example # Show all groups in RDP-Tcp security settings: Install-SintezRDSModuleServer -View -H RDSH1,RDSH2,RDSH3 .LINK http://www.heavenbay.ru/app/sintez/help/module/rds#installserver #> [CmdletBinding()] Param( [alias("SH")] [array]$RDSH, [alias("D")] [string]$Domain, [alias("G")] [string]$Group, [alias("R")] [switch]$Remove, [alias("V")] [switch]$View, [alias("C")] [switch]$Cred ) $ErrorActionPreference = "stop" if (!$RDSH) {[array]$RDSH = $ENV:COMPUTERNAME} if ($Cred -eq $true) { [PSCredential]$Cred = Get-Credential } else { [PSCredential]$Cred = [System.Management.Automation.PSCredential]::Empty } if ($Remove -eq $true) { foreach ($SH in $RDSH) { Write-Host "" Write-Host "Server is $SH`:" Try { ((gwmi -ComputerName $SH -Credential $Cred -Namespace "root\CIMV2\TerminalServices" -Class Win32_TSPermissionsSetting).where({$_.TerminalName -eq "RDP-Tcp"})).RestoreDefaults() | Out-Null If (!$Error) {Write-Host "Done" -BackgroundColor Black -ForegroundColor Green} } Catch [System.Management.Automation.MethodInvocationException] { Write-Host "Check that RDS-RD-Server role is installed on this PC." -BackgroundColor Black -ForegroundColor Red } Catch [System.Runtime.InteropServices.COMException] { Write-Host "RDSH is unavailable. Probably wrong IP/FQDN or firewall issues." -BackgroundColor Black -ForegroundColor Red } Catch [System.UnauthorizedAccessException] { Write-Host "Access to a remote broker is denided. Start cmdlet with a key '-C' to set the right credentials." -BackgroundColor Black -ForegroundColor Red Write-Host "" Break } } Write-Host "" Write-Host "Complited!" Write-Host "" break } if ($View -eq $true) { foreach ($SH in $RDSH) { Write-Host "" Write-Host "Server is $SH`:" Try { $v = ((gwmi -ComputerName $SH -Credential $Cred -Namespace "root\CIMV2\TerminalServices" -Class Win32_TSPermissionsSetting).where({$_.TerminalName -eq "RDP-Tcp"})).StringSecurityDescriptor [regex]::matches($v, "S-1-5-\d+-\d+-\d+-\d+-\d+").Groups.Value | %{Write-Host (New-Object System.Security.Principal.SecurityIdentifier($_)).Translate([System.Security.Principal.NTAccount]).Value -ForegroundColor Yellow -BackgroundColor Black} } Catch [System.Management.Automation.PSArgumentException] { Write-Host "There are no groups." -ForegroundColor Yellow -BackgroundColor Black } Catch [System.Runtime.InteropServices.COMException] { Write-Host "RDSH is unavailable. Probably wrong IP/FQDN or firewall issues." -BackgroundColor Black -ForegroundColor Red } Catch [System.UnauthorizedAccessException] { Write-Host "Access to a remote broker is denided. Start cmdlet with a key '-C' to set the right credentials." -BackgroundColor Black -ForegroundColor Red Write-Host "" Break } } Write-Host "" Write-Host "Complited!" Write-Host "" break } $Group = $Domain + "\" + $Group foreach ($SH in $RDSH) { Write-Host "" Write-Host "Server is $SH`:" Try { ((gwmi -ComputerName $SH -Credential $Cred -Namespace "root\CIMV2\TerminalServices" -Class Win32_TSPermissionsSetting).where({$_.TerminalName -eq "RDP-Tcp"})).AddAccount($Group,2) | Out-Null If (!$Error) {Write-Host "Done" -BackgroundColor Black -ForegroundColor Green} } Catch [System.Runtime.InteropServices.COMException] { Write-Host "RDSH is unavailable. Probably wrong IP/FQDN or firewall issues." -BackgroundColor Black -ForegroundColor Red } Catch [System.Management.Automation.MethodInvocationException] { Write-Host "Wrong domain/group. Please restart script with right params." -ForegroundColor Red -BackgroundColor Black Break } Catch [System.UnauthorizedAccessException] { Write-Host "Access to a remote broker is denided. Start cmdlet with a key '-C' to set the right credentials." -BackgroundColor Black -ForegroundColor Red Write-Host "" Break } } Write-Host "" Write-Host "Complited!" Write-Host "" } function Install-SintezRDSModuleClient { <# .Synopsis Add/Remove settings for RDS module on client PC. .Description Add/Remove registry tree "rdsmc" and .js file (WINDIR) for SINTEZ App RDS module on client PC. This script MUST be started as local Administrator. .Parameter Remove -Remove [-R] - Uninstall changes. .Example # Install RDS module settings: Install-SintezRDSModuleClient .Example # Uninstall RDS module settings: Install-SintezRDSModuleClient -Remove .LINK http://www.heavenbay.ru/app/sintez/help/module/rds#installclient #> [CmdletBinding()] Param( [switch]$Remove ) $win = $ENV:SYSTEMROOT $winjs = $win -replace "\\","\\" $RegPath = "HKLM:\SOFTWARE\Classes\rdsmc" $ErrorActionPreference = "stop" if ($Remove -eq $true) { Try { Remove-Item -Path $RegPath -Force -Recurse } Catch [System.Security.SecurityException] { Write-Host "Please, start new powershell session with local administrator rights and execute the cmdlet again." -BackgroundColor Black -ForegroundColor Red Write-Host "" Break } Catch [System.Management.Automation.ItemNotFoundException] { Write-Host "Registry: no item. Skipped..." -BackgroundColor Black -ForegroundColor Yellow } Try { Remove-Item -Path "$win\SnitezRDSMC.js" -Force } Catch [System.Management.Automation.ItemNotFoundException] { Write-Host "JS file: no item. Skipped..." -BackgroundColor Black -ForegroundColor Yellow } Write-Host "" Write-Host "Complited" -BackgroundColor Black -ForegroundColor Green Write-Host "" break } Try { New-Item -Path $RegPath -Value "URL:Remote Desktop Connection Management Console" -Force | Out-Null } Catch [System.Security.SecurityException] { Write-Host "Please, start new powershell session with local administrator rights and execute the cmdlet again." -BackgroundColor Black -ForegroundColor Red Write-Host "" Break } New-ItemProperty -Path $RegPath -Name "URL Protocol" -Force | Out-Null New-Item -Path "$RegPath\DefaultIcon" -Value "$win\System32\mstsc.exe" -Force | Out-Null New-Item -Path "$RegPath\shell\open\command" -Value "wscript.exe $win\SnitezRDSMC.js %1" -Force | Out-Null [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String(" dmFyIHN0ckFyZ3M9KFdTY3JpcHQuQXJndW1lbnRzKDApKQp2YXIgcHJlZml4PSdyZHNtYzovLycKc3RyQXJncz1zdHJBcmdzLnJlcGxhY2UocHJlZml4LCAn JykKc3RyQXJncz1zdHJBcmdzLnNwbGl0KCcvJykKdmFyIHNoZWxsID0gbmV3IEFjdGl2ZVhPYmplY3QoIldTY3JpcHQuU2hlbGwiKQppZiAoc3RyQXJnc1sw XSA9PSAic2hhZG93IikgewogICAgdmFyIGFwcD0nJVdJTkRJUiVcXHN5c3RlbTMyXFxtc3RzYy5leGUnCiAgICBzaGVsbC5FeGVjKGFwcCArICIgL3Y6IiAr IHN0ckFyZ3NbMV0gKyAiIC9zaGFkb3c6IiArIHN0ckFyZ3NbMl0gKyAiIC9jb250cm9sIC9ub2NvbnNlbnRwcm9tcHQiKQp9IGVsc2UgaWYgKHN0ckFyZ3Nb MF0gPT0gIm1zcmEiKSB7CiAgICB2YXIgYXBwPSclV0lORElSJVxcc3lzV09XNjRcXG1zcmEuZXhlJzsKICAgIHNoZWxsLkV4ZWMoYXBwICsgIiAvb2ZmZXJS QSAiICsgc3RyQXJnc1sxXSkKfSBlbHNlIGlmIChzdHJBcmdzWzBdID09ICJSRFAiKSB7CiAgICB2YXIgYXBwPSclV0lORElSJVxcc3lzdGVtMzJcXG1zdHNj LmV4ZSc7CiAgICBzaGVsbC5FeGVjKGFwcCArICIgL3Y6IiArIHN0ckFyZ3NbMV0pCn0gZWxzZSB7CiAgICBhbGVydCgnU29tZXRoaW5nIGdvZXMgd3Jvbmch Jyk7Cn0K ")) | Out-File -FilePath "$win\SnitezRDSMC.js" -Force Write-Host "" Write-Host "Complited!" -BackgroundColor Black -ForegroundColor Green Write-Host "" } function Start-RDSConnect { <# .Synopsis Start RDS console. .Description Used for getting user list and starting RDP connection. .Parameter Broker Broker [B] - RDCB FQDN. Ex.: RDCB1.domain.com .Parameter Credential Credential [C] - Connection credentials switch. No params are needed. .Example # Start console with credentials prompt: Start-RDSConnect -B RDCB1.domain.com -C .Example # Start console without credentials prompt: Start-RDSConnect -Broker RDCB1.domain.com .LINK http://www.heavenbay.ru/app/sintez/help/module/rds#console #> [CmdletBinding()] Param( [Parameter(Mandatory=$true)] [alias("B")] [string]$Broker, [alias("C")] [switch]$Cred ) if ($Cred -eq $true) { [PSCredential]$Cred = Get-Credential } else { [PSCredential]$Cred = [System.Management.Automation.PSCredential]::Empty } $col = @{} $newCol = @{} Try { Get-WmiObject -Credential $Cred -ComputerName $Broker -Query "SELECT Alias, Name FROM Win32_RDSHCollection" -Namespace root\CIMv2\rdms | %{$col.Add($_.alias, $_.name)} } Catch [System.UnauthorizedAccessException] { Write-Host "Access to a remote broker is denided. Start cmdlet with a key '-C' to set the right credentials." -BackgroundColor Black -ForegroundColor Red Write-Host "" Break } Catch [System.Runtime.InteropServices.COMException] { Write-Host "Broker is unavailable. Probably wrong IP/FQDN or firewall issues." -BackgroundColor Black -ForegroundColor Red Write-Host "" Break } Get-WmiObject -Credential $Cred -ComputerName $Broker -Query "SELECT Name, CollectionAlias FROM Win32_RDSHServer" -Namespace root\CIMv2\rdms | %{$newCol.Add(($_.Name),$col[$_.CollectionAlias])} function getStateName([int]$StateId) { [string]$rez = "###"; switch ($StateId) { 0 {$rez = "Active"} 1 {$rez = "Active, Minimized"} 2 {$rez = "Query"} 3 {$rez = "Shadow"} 4 {$rez = "Disconnected"} 5 {$rez = "Idle"} 6 {$rez = "Listen"} 7 {$rez = "Reset"} 8 {$rez = "Down"} 9 {$rez = "Init"} default {$rez = "Invalid State"} } return $rez } function SessionAction { Param ( [parameter(ValueFromPipelineByPropertyName)] [int[]]$SID, [parameter(ValueFromPipelineByPropertyName)] [string[]]$UserName, [parameter(ValueFromPipelineByPropertyName)] [string[]]$Host ) Begin { $Sessions = @() } Process { $Sessions += "$UserName;$SID;$Host" } End { If ($Sessions.Count -le 0) { Write-Host "" Write-Host "No sessions. Do nothing." Write-Host "" } ElseIf ($Sessions.Count -eq 1) { start-process rdsmc://shadow/$Host/$SID } Else { Write-Host "It's a bad idea to start 100500 RDP sessions. I limit them to 2." -BackgroundColor Black -ForegroundColor Yellow Write-Host "" foreach($S in $Sessions[0..1]) { [int]$SID = $S.Split(";")[1] [string]$Host = $S.Split(";")[2] start-process rdsmc://shadow/$Host/$SID } } } } Get-WmiObject -Credential $Cred -ComputerName $Broker -Namespace "root\CIMv2" -Query "SELECT UserName,IdleTime,CreateTime,HostServer,DomainName,SessionState,UnifiedSessionID FROM Win32_SessionDirectorySessionEx" ` | Select UserName,` @{Label="SID";Expression={$_.UnifiedSessionID}},` @{Label="Host";Expression={$_.HostServer}},` @{Label="Activity";Expression={getStateName($_.SessionState)}},` @{Label="Collection";Expression={$newCol[$_.HostServer]}},` @{Label="Creation Time";Expression={[datetime]::ParseExact(($_.CreateTime -replace "\..*",""),"yyyyMMddHHmmss", $null)}},` @{Label="Domain";Expression={$_.DomainName}},` @{Label="Idle";Expression={"{0:N0}" -f ([timespan]::frommilliseconds($_.IdleTime)).TotalMinutes}} ` | Out-GridView -PassThru -Title "RDS Sessions" ` | SessionAction } Export-ModuleMember -Function "Install-SintezRDSModuleServer", "Install-SintezRDSModuleClient", "Start-RDSConnect" |