PSRdSessions.psm1
<# Connect Method void Connect(Cassia.ITerminalServicesSession target, string password, bool synchronous), void ITerminalServicesSession.Connect(Cassi... Disconnect Method void Disconnect(), void Disconnect(bool synchronous), void ITerminalServicesSession.Disconnect(), void ITerminalServicesSession.Disc... Equals Method bool Equals(System.Object obj) GetHashCode Method int GetHashCode() GetProcesses Method System.Collections.Generic.IList[Cassia.ITerminalServicesProcess] GetProcesses(), System.Collections.Generic.IList[Cassia.ITerminalS... GetType Method type GetType() Logoff Method void Logoff(), void Logoff(bool synchronous), void ITerminalServicesSession.Logoff(), void ITerminalServicesSession.Logoff(bool sync... MessageBox Method void MessageBox(string text), void MessageBox(string text, string caption), void MessageBox(string text, string caption, Cassia.Remo... StartRemoteControl Method void StartRemoteControl(System.ConsoleKey hotkey, Cassia.RemoteControlHotkeyModifiers hotkeyModifiers), void ITerminalServicesSessio... StopRemoteControl Method void StopRemoteControl(), void ITerminalServicesSession.StopRemoteControl() #> Function Open-RdSession { <# .SYNOPSIS Function to connect an RDP session without the password prompt .DESCRIPTION This function provides the functionality to start an RDP session without having to type in the password .PARAMETER ComputerName This can be a single computername or an array of computers to which RDP session will be opened .PARAMETER User The user name that will be used to authenticate .PARAMETER Password The password that will be used to authenticate .PARAMETER Credential The PowerShell credential object that will be used to authenticate against the remote system .PARAMETER Admin Sets the /admin switch on the mstsc command: Connects you to the session for administering a server .PARAMETER RDG Sets the /g parameters as Remote Desktop Gateaway .PARAMETER MultiMon Sets the /multimon switch on the mstsc command: Configures the Remote Desktop Services session monitor layout to be identical to the current client-side configuration .PARAMETER FullScreen Sets the /f switch on the mstsc command: Starts Remote Desktop in full-screen mode .PARAMETER Public Sets the /public switch on the mstsc command: Runs Remote Desktop in public mode .PARAMETER Width Sets the /w:<width> parameter on the mstsc command: Specifies the width of the Remote Desktop window .PARAMETER Height Sets the /h:<height> parameter on the mstsc command: Specifies the height of the Remote Desktop window .NOTES Name: Open-RdSession Author: Jaap Brasser DateUpdated: 2016-10-28 Version: 1.2.5 .LINK https://gallery.technet.microsoft.com/scriptcenter/Connect-Mstsc-Open-RDP-2064b10b .EXAMPLE A remote desktop session to server01 will be created using the credentials of contoso\jaapbrasser Open-RdSession -ComputerName server01 -User open\jdoe -cred (Get-CredentialByRegistry (whoami)) #> [cmdletbinding(SupportsShouldProcess,DefaultParametersetName='UserPassword')] param ( [Parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Mandatory=$true)] [Alias('CN')] [string[]] $ComputerName, [Parameter(ParameterSetName='UserPassword',Mandatory=$true)] [Alias('U','NtAccountName')] [string] $User = (whoami.exe), [Parameter(ParameterSetName='UserPassword',Mandatory=$true)] [Alias('P')] [string] $Password, [Parameter(ParameterSetName='Credential',Mandatory=$true)] [Alias('C')] [PSCredential] $Credential = $null, [Alias('A')] [switch] $Admin, [Alias("g")] [string] $RDG, [Alias('MM')] [switch] $MultiMon, [Alias('F')] [switch] $FullScreen, [Alias('Pu')] [switch] $Public, [Alias('W')] [int] $Width, [Alias('H')] [int] $Height, [Alias('WT')] [switch] $Wait ) begin { [string]$MstscArguments = '' switch ($true) { {$Admin} {$MstscArguments += '/admin '} {$RDG} {$MstscArguments += "/g:$RDG "} {$MultiMon} {$MstscArguments += '/multimon '} {$FullScreen} {$MstscArguments += '/f '} {$Public} {$MstscArguments += '/public '} {$Width} {$MstscArguments += "/w:$Width "} {$Height} {$MstscArguments += "/h:$Height "} } if ($Credential) { $User = $Credential.UserName $Password = $Credential.GetNetworkCredential().Password } } process { foreach ($Computer in $ComputerName) { $ProcessInfo = New-Object System.Diagnostics.ProcessStartInfo $Process = New-Object System.Diagnostics.Process # Remove the port number for CmdKey otherwise credentials are not entered correctly if ($Computer.Contains(':')) { $ComputerCmdkey = ($Computer -split ':')[0] } else { $ComputerCmdkey = $Computer } $ProcessInfo.FileName = "$($env:SystemRoot)\system32\cmdkey.exe" $ProcessInfo.Arguments = "/generic:TERMSRV/$ComputerCmdkey /user:$User /pass:$($Password)" $ProcessInfo.WindowStyle = [System.Diagnostics.ProcessWindowStyle]::Hidden $Process.StartInfo = $ProcessInfo if ($PSCmdlet.ShouldProcess($ComputerCmdkey,'Adding credentials to store')) { [void]$Process.Start() } $ProcessInfo.FileName = "$($env:SystemRoot)\system32\mstsc.exe" $ProcessInfo.Arguments = "$MstscArguments /v $Computer" $ProcessInfo.WindowStyle = [System.Diagnostics.ProcessWindowStyle]::Normal $Process.StartInfo = $ProcessInfo if ($PSCmdlet.ShouldProcess($Computer,'Connecting mstsc')) { [void]$Process.Start() if ($Wait) { $null = $Process.WaitForExit() } } } } } function Convert-RdSession { <# .SYNOPSIS Converti un objet cassia.session en PSObject .DESCRIPTION retourne la session sous une forme efficiante pour interpretation .PARAMETER Sessions Cassia.Session .EXAMPLE $RDSessions = [Cassia.TerminalServicesManager]::new().GetRemoteServer('vdiv03') $RDSessions.Open() $RDSessions.GetSessions() | Convert-RdSession -DetailsTimeOut 10 -ResolveIp .NOTES Alban LOPEZ 2018 alban.lopez@gmail.com http://git/PowerTech/ #> [CmdletBinding()] param ( [Parameter(ValueFromPipeline = $true)]$Sessions, # [Cassia.Impl.TerminalServicesSession] [int]$DetailsTimeOut, [switch]$ResolveIp ) begin { $Count = 0 $UnResolvableIP = @() $poolstart = (get-date) # $NtAccount = New-Object System.Security.Principal.NTAccount # } process { foreach ($Session in $Sessions) { if($Session -is [Cassia.Impl.TerminalServicesSession]){ # $start = (get-date) $Count++ $duree = $("$($Session.IdleTime)").split(':') #$NtAccountName = $Session.UserAccount [hashtable]@{ ComputerName = $Session.server.ServerName SessionID = "$($Session.SessionID)" State = "$($Session.ConnectionState)" Sid = [string]$(if($Session.UserAccount){ try { New-Object System.Security.Principal.NTAccount($Session.UserAccount).Translate([System.Security.Principal.SecurityIdentifier]).Value } catch { Write-LogStep -prefixe "L.$($_.InvocationInfo.ScriptLineNumber) %caller%" "Recuperation SID [$($Session.UserAccount)] ","$_" Error } }else{'-'}) NtAccountName = [string]$Session.UserAccount IPAddress = [string]$( # write-verbose "$IP : $($Session.SessionID) - $(((get-date)-$start).TotalSeconds)" if($Session.WindowStationName -eq 'Console') { # sur la session console sera affiche l'ip du serveur [string][System.Net.Dns]::GetHostAddresses($Session.server.ServerName).IPAddressToString } else { # write-color $Session.UserAccount, $Session.RemoteEndPoint.Address, $Session.ClientIPAddress,$(if($Session.RemoteEndPoint.Address -match $Session.ClientIPAddress){' === '}else{' XXX '}) -fore cyan,magenta,yellow,red if($Session.RemoteEndPoint.Address -and $Session.ClientIPAddress){ # si il y a les 2 IP on prefere ClientIPAddress, car l'autre et bizare avec les Platines $IP ="$($Session.ClientIPAddress)/$($Session.RemoteEndPoint.Address)" } elseif ($Session.RemoteEndPoint.Address -and $Session.RemoteEndPoint.Address -notmatch '^127\.0\.\d+\.\d+') { $IP = $Session.RemoteEndPoint.Address -replace('(.+):\d*','$1') } else { $IP = $Session.ClientIPAddress } if ($IP -eq [string][System.Net.Dns]::GetHostAddresses($Session.server.ServerName).IPAddressToString) { 'HTML5-Direct' } elseif ($IP -match '^10\.12\d\.\d+\.\d+' -and $UnResolvableIP -notcontains $IP) { if ($ResolveIp) { # Write-LogStep "Tentative de resolution IP-TSG ", $IP wait $( try { $fqdn = (Get-DnsClientCache -data $IP -ea Stop).name | Sort-Object -Unique $fqdn # Write-LogStep "Get-DnsClientCache [$IP]", $fqdn OK } catch { try { $fqdn = (Resolve-DnsName $IP -Server ($Session.server.ServerName.split('.')[-2..-1] -join('.')) -ea Stop).nameHost $fqdn # Write-LogStep "Resolve-DnsName [$IP]", $fqdn OK Test-TcpPort $fqdn -port 135 -Quick | Out-Null # permet de rensegner le cacheDNS } catch { try { $fqdn = [System.Net.Dns]::gethostentry($IP).HostName $fqdn # Write-LogStep "[Net.Dns]::gethostentry($IP)", $fqdn OK Test-TcpPort $fqdn -port 135 -Quick | Out-Null # permet de rensegner le cacheDNS } catch { $IP $UnResolvableIP += $IP Write-LogStep ` -messages '',$_ Error } } } "TSG:$IP" ) -join(", `n") } else { "TSG:$IP" } } elseif ($IP -match '^172\.16\.\d+\.\d+') { 'HTML5-HAProxy' } else { $IP } } # write-verbose "$IP : $($Session.SessionID) - $(((get-date)-$start).TotalSeconds)" ) ClientName = "$($Session.ClientName)" Protocole = $( switch -Regex ($Session.WindowStationName) { '^Session' { 'Flexy-RDP' } '^RDP' { 'WinTS-RDP' } '^ICA' { 'Citrix-ICA' } '^Console' {'VMWare-Console'} Default {$Session.WindowStationName} } ) ClientBuildNumber = "$($Session.ClientBuildNumber)" # [System.DateTime] LoginTime = $( if ("$($Session.LoginTime)") {$Session.LoginTime.ToString()} else {"-"}) DisconnectTime = $( if ("$($Session.DisconnectTime)") {$Session.DisconnectTime.ToString()} else {"-"}) ConnectTime = $( if ("$($Session.ConnectTime)") {$Session.ConnectTime.ToString()} else {"-"}) Inactivite = if($duree){"$($duree[0].replace('.','j '))h $($duree[1])m $($duree[2].split('.')[0])s"}else{$null} Screen = "$($Session.ClientDisplay.HorizontalResolution)*$($Session.ClientDisplay.VerticalResolution) / $($Session.ClientDisplay.BitsPerPixel)Bits" Process = $( if ($DetailsTimeOut -and (((get-date)-$poolstart).TotalSeconds -lt $DetailsTimeOut)) {$Session.getprocesses().ProcessName} ) # Timer = ((get-date)-$start).TotalSeconds } } elseif ($Session) { # [hashtable] $Session } } } end { Write-LogStep "Collecte terminee [$($Session.server.ServerName)] ", "[$($Count) RdChannels]" OK } } function Get-RdComputer { <# .SYNOPSIS Construis l'object destiner a interoger les sessions TS .DESCRIPTION Retourne un object Cassia qui pourra etre utiliser et reutiliser par la suite .PARAMETER TSRemoteServer Computer cassia connector [Cassia.Impl.TerminalServer] .PARAMETER CassiaErrorServer Object issue de la fonction Get-RdComputer, mais incompatible pour la suite .PARAMETER ComputerName Fqdn de l'ordinateur a interoger, si il est fournis seul les autres parametre (IP, Port...) seront calcule .PARAMETER IP Adresse IP .PARAMETER Port22 Etat du port Tcp-IP 22, si fourni il ne sera pas reteste .PARAMETER Port135 Etat du port Tcp-IP 135, si fourni il ne sera pas reteste .PARAMETER Port445 Etat du port Tcp-IP 445, si fourni il ne sera pas reteste .EXAMPLE contruis le handler Cassia pour vdiv03 et vdiv05 'vdiv03', 'vdiv05' | Get-RdComputer .NOTES Alban LOPEZ 2019 alban.lopez@gmail.com http://git/PowerTech/ #> [CmdletBinding()] param ( [Parameter(ValueFromPipeline = $true, Mandatory = $true, ParameterSetName = 'cassia')] [Cassia.Impl.TerminalServer]$TSRemoteServer = $null, [Parameter(ValueFromPipeline = $true, Mandatory = $true, ParameterSetName = 'CassiaError')] [hashtable]$CassiaErrorServer = $null, [Parameter(ValueFromPipeline = $true, Mandatory = $true, ParameterSetName = 'Simple')] [Parameter(ValueFromPipelineByPropertyName=$true, Mandatory = $true, ParameterSetName = 'Dragonfly')] [string]$ComputerName = $null, [Parameter(ValueFromPipelineByPropertyName=$true, Mandatory = $true, ParameterSetName = 'Dragonfly')] [string]$IP = $null, [Parameter(ValueFromPipelineByPropertyName=$true, Mandatory = $true, ParameterSetName = 'Dragonfly')] $Port22 = $null, [Parameter(ValueFromPipelineByPropertyName=$true, Mandatory = $true, ParameterSetName = 'Dragonfly')] $Port135 = $null, [Parameter(ValueFromPipelineByPropertyName=$true, Mandatory = $true, ParameterSetName = 'Dragonfly')] $Port445 = $null ) begin { $TSManager = New-Object Cassia.TerminalServicesManager # [Cassia.TerminalServicesManager]::new() $SrvList = @() $PipeStart = (get-date) } process { $ThisStart = (get-date) # Write-Object $PSCmdlet.ParameterSetName -foreGroundColor DarkBlue try { switch($PSCmdlet.ParameterSetName){ 'cassia' { $TSRemoteServer.Open() if($TSRemoteServer.IsOpen){ $TSRemoteServer } else { $IP = '-' $State = 'Connexion Failed' Throw '[Cassia.TerminalServicesManager] Connexion Failed !' } } 'Simple' { try{ $IP = [string][System.Net.Dns]::GetHostAddresses($ComputerName).IPAddressToString [PSCustomObject]@{ ComputerName = $ComputerName IP = $IP Port22 = (Test-TcpPort $ComputerName -port 22 -Confirm -Quick) Port135 = (Test-TcpPort $ComputerName -port 135 -Confirm -Quick) Port445 = (Test-TcpPort $ComputerName -port 445 -Confirm -Quick) } | Get-RdComputer } catch { $IP = '-' $State = 'HS' Throw '[Pas de resolution DNS]' } } 'Dragonfly' { if ($IP -like '*.*.*.*') { if ($Port135 -and $Port445) { $TSRemoteServer = $TSManager.GetRemoteServer($ComputerName) $TSRemoteServer.Open() if($TSRemoteServer.IsOpen){ $TSRemoteServer } else { $State = 'Connexion Failed' Throw '[Cassia.TerminalServicesManager] Connexion Failed !' } } elseif ($Port22) { $State = 'Linux' Throw '[Impossible de lister les Sessions]' } else { # [Cassia.Impl.TerminalServicesSession]::new($TSRemoteServer,0) $State = 'HS' Throw '[Tcp-Ip Down]' } } } 'CassiaError' { $CassiaErrorServer } } } catch { Write-LogStep -prefixe "L.$($_.InvocationInfo.ScriptLineNumber) %caller%" "Collecte des Sessions [$computerName] ","$_" Error # [PSCustomObject] [hashtable]@{ ComputerName = $ComputerName SessionID = '-' State = $State Sid = '-' NtAccountName = $null IPAddress = $IP ClientName = '-' Protocole = '-' ClientBuildNumber = '-' LoginTime = '-' DisconnectTime = "Error L.$($_.InvocationInfo.ScriptLineNumber): $_" ConnectTime = '-' Inactivite = "$(((get-date)-$ThisStart).TotalSeconds) Sec" Screen = '-' Process = $null } } } end { # Write-LogStep 'Collecte des RdHandler ', "Duree $(((get-date)-$PipeStart).TotalSeconds) Sec" ok } } function Get-RdSession { <# .SYNOPSIS Interroge des serveurs a la recherche de session .DESCRIPTION retourne une liste d'entree relative au session et serveur .PARAMETER TSRemoteServer Computer cassia connector [Cassia.Impl.TerminalServer] .PARAMETER CassiaErrorServer Object issue de la fonction Get-RdComputer, mais incompatible pour la suite .PARAMETER ComputerName Fqdn de l'ordinateur a interoger, si il est fournis seul les autres parametre (IP, Port...) seront calcule .PARAMETER IP Adresse IP .PARAMETER Port22 Etat du port Tcp-IP 22, si fourni il ne sera pas reteste .PARAMETER Port135 Etat du port Tcp-IP 135, si fourni il ne sera pas reteste .PARAMETER Port445 Etat du port Tcp-IP 445, si fourni il ne sera pas reteste .PARAMETER Identity filtre ID ou NtAccountName .EXAMPLE Se connecte a 2 user et cherche la session 6 sur chacun d'entre eux 'vps.opt2','vdiv03' | Get-RdComputer | Get-RdSession -Identity 6 .EXAMPLE se connecte au vdiv03 et cherche la session '*\user' Get-RdComputer vdiv03 | Get-RdSession -Identity '*\user' .NOTES Alban LOPEZ 2019 alban.lopez@gmail.com http://git/PowerTech/ #> [cmdletbinding(DefaultParameterSetName='ComputerName')] param ( [Parameter(ValueFromPipeline = $true, Mandatory = $true, ParameterSetName = 'cassia')] [Cassia.Impl.TerminalServer]$TSRemoteServer = $null, [Parameter(ValueFromPipeline = $true, Mandatory = $true, ParameterSetName = 'CassiaError')] [hashtable]$CassiaErrorServer = $null, [Parameter(ValueFromPipeline = $true, Mandatory = $true, ParameterSetName = 'Simple')] [Parameter(ValueFromPipelineByPropertyName=$true, Mandatory = $true, ParameterSetName = 'Dragonfly')] [string]$ComputerName = $null, [Parameter(ValueFromPipelineByPropertyName=$true, Mandatory = $true, ParameterSetName = 'Dragonfly')] [string]$IP = $null, [Parameter(ValueFromPipelineByPropertyName=$true, Mandatory = $true, ParameterSetName = 'Dragonfly')] $Port22 = $null, [Parameter(ValueFromPipelineByPropertyName=$true, Mandatory = $true, ParameterSetName = 'Dragonfly')] $Port135 = $null, [Parameter(ValueFromPipelineByPropertyName=$true, Mandatory = $true, ParameterSetName = 'Dragonfly')] $Port445 = $null, [alias('SessionId','NtAccountName','UserAccount')] [Parameter(ParameterSetName = 'cassia')] [Parameter(ParameterSetName = 'CassiaError')] [Parameter(ParameterSetName = 'Simple')] [Parameter(ParameterSetName = 'Dragonfly')] $Identity = $null ) begin { $PipeStart = (get-date) } process { # Write-Object $PSCmdlet.ParameterSetName -foreGroundColor red switch($PSCmdlet.ParameterSetName){ 'cassia' { $TSRemoteServer.Open() if($TSRemoteServer.IsOpen){ try { if($Identity -is [int]){ $TSRemoteServer.GetSession($Identity) } elseif($Identity -is [string]){ $TSRemoteServer.GetSessions() | Where-Object{$_.UserAccount -like $Identity} } else { $TSRemoteServer.GetSessions() } # } catch [System.Runtime.InteropServices.ExternalException] { # Write-LogStep 'Collecte des RdSession ', $_ Error } catch { [hashtable]@{ ComputerName = $TSRemoteServer.servername SessionID = '-' State = 'HS' Sid = '-' NtAccountName = $null IPAddress = $null ClientName = '-' Protocole = '-' ClientBuildNumber = '-' LoginTime = '-' DisconnectTime = "Error L.$($_.InvocationInfo.ScriptLineNumber): $_" ConnectTime = '-' Inactivite = '-' Screen = '-' Process = $null } Write-LogStep "Collecte refuser [$($TSRemoteServer.servername)]", $_ Error } } } 'Simple' { $ComputerName | Get-RdComputer | Get-RdSession -Identity $Identity } 'Dragonfly' { [PSCustomObject]@{ ComputerName = $ComputerName IP = $IP Port22 = $Port22 Port135 = $Port135 Port445 = $Port445 } | Get-RdComputer | Get-RdSession -Identity $Identity } 'CassiaError' { $CassiaErrorServer } } } end { Write-LogStep 'Collecte des RdSession ', "Duree $(((get-date)-$PipeStart).TotalSeconds) Sec" ok } } function Stop-RdSession { <# .SYNOPSIS Ferme une ou plusieurs sessions distante .DESCRIPTION Retourne les objects sessions qui ont appliqué le logOff() .PARAMETER TSRemoteServer Computer cassia connector [Cassia.Impl.TerminalServer] .PARAMETER CassiaErrorServer Object issue de la fonction Get-RdComputer, mais incompatible pour la suite .PARAMETER ComputerName Fqdn de l'ordinateur a interoger, si il est fournis seul les autres parametre (IP, Port...) seront calcule .PARAMETER IP Adresse IP .PARAMETER Port22 Etat du port Tcp-IP 22, si fourni il ne sera pas reteste .PARAMETER Port135 Etat du port Tcp-IP 135, si fourni il ne sera pas reteste .PARAMETER Port445 Etat du port Tcp-IP 445, si fourni il ne sera pas reteste .PARAMETER Identity filtre ID ou NtAccountName .EXAMPLE Stop-RdSession .NOTES Alban LOPEZ 2019 alban.lopez@gmail.com http://git/PowerTech/ #> [CmdletBinding()] param ( [Parameter(ValueFromPipeline = $true, Mandatory = $true, ParameterSetName = 'cassia')] [Cassia.Impl.TerminalServicesSession]$TerminalServicesSession = $null, [Parameter(ValueFromPipeline = $true, Mandatory = $true, ParameterSetName = 'CassiaError')] [hashtable]$CassiaErrorServer = $null, [Parameter(ValueFromPipeline = $true, Mandatory = $true, ParameterSetName = 'Simple')] [Parameter(ValueFromPipelineByPropertyName=$true, Mandatory = $true, ParameterSetName = 'Dragonfly')] [string]$ComputerName = $null, [Parameter(ValueFromPipelineByPropertyName=$true, Mandatory = $true, ParameterSetName = 'Dragonfly')] [string]$IP = $null, [Parameter(ValueFromPipelineByPropertyName=$true, Mandatory = $true, ParameterSetName = 'Dragonfly')] $Port22 = $null, [Parameter(ValueFromPipelineByPropertyName=$true, Mandatory = $true, ParameterSetName = 'Dragonfly')] $Port135 = $null, [Parameter(ValueFromPipelineByPropertyName=$true, Mandatory = $true, ParameterSetName = 'Dragonfly')] $Port445 = $null, [alias('SessionId','NtAccountName','UserAccount')] [Parameter(ParameterSetName = 'CassiaError')] [Parameter(ParameterSetName = 'Simple')] [Parameter(ParameterSetName = 'Dragonfly')] $Identity ) begin { $Targets = @() } process { # Write-Object $PSCmdlet.ParameterSetName switch($PSCmdlet.ParameterSetName){ 'cassia' { $Targets += $TerminalServicesSession } 'Simple' { $ComputerName | Get-RdComputer | Get-RdSession -Identity $Identity | Stop-RdSession } 'Dragonfly' { [PSCustomObject]@{ ComputerName = $ComputerName IP = $IP Port22 = $Port22 Port135 = $Port135 Port445 = $Port445 } | Get-RdComputer | Get-RdSession -Identity $Identity | Stop-RdSession } 'CassiaError' { $CassiaErrorServer } } } end { foreach ($Target in $Targets) { try { $Target.Logoff() $Target Write-LogStep "Fermeture de session [$($Target.Server.ServerName):$($Target.SessionId)]","$([string]$Target.UserAccount)" OK } catch { Write-LogStep "Fermeture de session ",$PSBoundParameters Error } } } } function Send-RdSession { <# .SYNOPSIS envoy un Message a une session distante .DESCRIPTION [Descriptif en quelques lignes] .PARAMETER TSRemoteServer Computer cassia connector [Cassia.Impl.TerminalServer] .PARAMETER CassiaErrorServer Object issue de la fonction Get-RdComputer, mais incompatible pour la suite .PARAMETER ComputerName Fqdn de l'ordinateur a interoger, si il est fournis seul les autres parametre (IP, Port...) seront calcule .PARAMETER IP Adresse IP .PARAMETER Port22 Etat du port Tcp-IP 22, si fourni il ne sera pas reteste .PARAMETER Port135 Etat du port Tcp-IP 135, si fourni il ne sera pas reteste .PARAMETER Port445 Etat du port Tcp-IP 445, si fourni il ne sera pas reteste .PARAMETER Identity filtre ID ou NtAccountName .PARAMETER Title Title en haut du PopUp .PARAMETER Message Corp du PopUp .PARAMETER Footer Signature en bas du message .EXAMPLE liste toutes les sessions Open sur vdiv05 puis envoy un message 'vdiv05' | Get-RdSession -identity 'open\*' | send-RdSession -Message 'Merci de fermer vos session' .EXAMPLE liste toutes les sessions cecaf sur vdiv05 puis envoy un message $sessions = 'vdiv05' | Get-RdSession -identity '*alopez' $sessions | Send-RdSession -Message 'Merci de fermer vos session' start-sleep -s 30 $sessions | Stop-RdSession .NOTES Alban LOPEZ 2019 alban.lopez@gmail.com http://git/PowerTech/ #> [CmdletBinding()] param ( [Parameter(ValueFromPipeline = $true, Mandatory = $true, ParameterSetName = 'cassia')] [Cassia.Impl.TerminalServicesSession]$TerminalServicesSession = $null, [Parameter(ValueFromPipeline = $true, Mandatory = $true, ParameterSetName = 'CassiaError')] [hashtable]$CassiaErrorServer = $null, [Parameter(ValueFromPipeline = $true, Mandatory = $true, ParameterSetName = 'Simple')] [Parameter(ValueFromPipelineByPropertyName=$true, Mandatory = $true, ParameterSetName = 'Dragonfly')] [string]$ComputerName = $null, [Parameter(ValueFromPipelineByPropertyName=$true, Mandatory = $true, ParameterSetName = 'Dragonfly')] [string]$IP = $null, [Parameter(ValueFromPipelineByPropertyName=$true, Mandatory = $true, ParameterSetName = 'Dragonfly')] $Port22 = $null, [Parameter(ValueFromPipelineByPropertyName=$true, Mandatory = $true, ParameterSetName = 'Dragonfly')] $Port135 = $null, [Parameter(ValueFromPipelineByPropertyName=$true, Mandatory = $true, ParameterSetName = 'Dragonfly')] $Port445 = $null, [alias('SessionId','NtAccountName','UserAccount')] [Parameter(ParameterSetName = 'CassiaError')] [Parameter(ParameterSetName = 'Simple')] [Parameter(ParameterSetName = 'Dragonfly')] $Identity, [string] $Title = 'Message de votre support', [string] $Message = '...', [string] $Footer = "$(whoami), Coaxis-Asp (0825 82 82 57)" ) begin { $Targets = @() } process { # Write-Object $PSCmdlet.ParameterSetName -fore DarkMagenta switch($PSCmdlet.ParameterSetName){ 'cassia' { $Targets += $TerminalServicesSession } 'Simple' { $Targets += $ComputerName | Get-RdComputer | Get-RdSession -Identity $Identity # | Send-RdSession -Title $Title -Message $Message -Footer $Footer } 'Dragonfly' { $Targets += [PSCustomObject]@{ ComputerName = $ComputerName IP = $IP Port22 = $Port22 Port135 = $Port135 Port445 = $Port445 } | Get-RdComputer | Get-RdSession -Identity $Identity # | Send-RdSession -Title $Title -Message $Message -Footer $Footer } 'CassiaError' { $CassiaErrorServer } } } end { foreach ($Target in ($Targets | Where-Object{$_.UserAccount})) { try { $Target.MessageBox("$Message`n`n$Footer",$Title) $Target Write-LogStep "Message en session [$($Target.Server.ServerName):$($Target.SessionId)]","$([string]$Target.UserAccount)" OK } catch { Write-LogStep "Message en session ",$PSBoundParameters Error } } } } function Request-RdSession { <# .SYNOPSIS Pose une Question Yes/No a une session distante .DESCRIPTION Fais apparaitre une PopUp avec la quetion et la possibilité de repondre par oui / non .PARAMETER TSRemoteServer Computer cassia connector [Cassia.Impl.TerminalServer] .PARAMETER CassiaErrorServer Object issue de la fonction Get-RdComputer, mais incompatible pour la suite .PARAMETER ComputerName Fqdn de l'ordinateur a interoger, si il est fournis seul les autres parametre (IP, Port...) seront calcule .PARAMETER IP Adresse IP .PARAMETER Port22 Etat du port Tcp-IP 22, si fourni il ne sera pas reteste .PARAMETER Port135 Etat du port Tcp-IP 135, si fourni il ne sera pas reteste .PARAMETER Port445 Etat du port Tcp-IP 445, si fourni il ne sera pas reteste .PARAMETER Identity filtre ID ou NtAccountName .PARAMETER Title Title en haut du PopUp .PARAMETER Message Corp du PopUp .PARAMETER Footer Signature en bas du message .PARAMETER TimeOut Delais pour repondre .EXAMPLE liste toutes les sessions Open sur vdiv05 puis envoy un message 'vdiv05' | Get-RdSession -identity 'open\*' | Request-RdSession -Message 'Etes vous majeur ?' | ft UserName,request,answer .EXAMPLE liste toutes les sessions cecaf sur vdiv05 puis envoy un message $sessions = 'vdiv05' | Get-RdSession -identity '*alopez' $sessions | Request-RdSession -title 'interdi au mineur' -Message 'Etes vous majeur ?' $sessions | ?{$_.answer -like 'no'} | Stop-RdSession .NOTES Alban LOPEZ 2019 alban.lopez@gmail.com http://git/PowerTech/ #> [CmdletBinding()] param ( [Parameter(ValueFromPipeline = $true, Mandatory = $true, ParameterSetName = 'cassia')] [Cassia.Impl.TerminalServicesSession]$TerminalServicesSession = $null, [Parameter(ValueFromPipeline = $true, Mandatory = $true, ParameterSetName = 'CassiaError')] [hashtable]$CassiaErrorServer = $null, [Parameter(ValueFromPipeline = $true, Mandatory = $true, ParameterSetName = 'Simple')] [Parameter(ValueFromPipelineByPropertyName=$true, Mandatory = $true, ParameterSetName = 'Dragonfly')] [string]$ComputerName = $null, [Parameter(ValueFromPipelineByPropertyName=$true, Mandatory = $true, ParameterSetName = 'Dragonfly')] [string]$IP = $null, [Parameter(ValueFromPipelineByPropertyName=$true, Mandatory = $true, ParameterSetName = 'Dragonfly')] $Port22 = $null, [Parameter(ValueFromPipelineByPropertyName=$true, Mandatory = $true, ParameterSetName = 'Dragonfly')] $Port135 = $null, [Parameter(ValueFromPipelineByPropertyName=$true, Mandatory = $true, ParameterSetName = 'Dragonfly')] $Port445 = $null, [alias('SessionId','NtAccountName','UserAccount')] [Parameter(ParameterSetName = 'CassiaError')] [Parameter(ParameterSetName = 'Simple')] [Parameter(ParameterSetName = 'Dragonfly')] $Identity, [string] $Title = 'Message de votre support', [string] $Message = '...', [string] $Footer = "$(whoami), Coaxis-Asp (0825 82 82 57)", [int] $TimeOut = 60 ) begin { $Targets = @() } process { # Write-Object $PSCmdlet.ParameterSetName -fore DarkMagenta switch($PSCmdlet.ParameterSetName){ 'cassia' { $Targets += $TerminalServicesSession } 'Simple' { $Targets += $ComputerName | Get-RdComputer | Get-RdSession -Identity $Identity # | Request-RdSession -Title $Title -Message $Message -Footer $Footer } 'Dragonfly' { $Targets += [PSCustomObject]@{ ComputerName = $ComputerName IP = $IP Port22 = $Port22 Port135 = $Port135 Port445 = $Port445 } | Get-RdComputer | Get-RdSession -Identity $Identity # | Request-RdSession -Title $Title -Message $Message -Footer $Footer } 'CassiaError' { $CassiaErrorServer } } } end { foreach ($Target in ($Targets | Where-Object{$_.UserAccount})) { try { Write-LogStep "Question en session [$($Target.Server.ServerName):$($Target.SessionId)]",$Target.UserAccount wait $ClickOn = $Target.MessageBox( "$Message`n`n$Footer", $Title, [Cassia.RemoteMessageBoxButtons]::YesNo, [Cassia.RemoteMessageBoxIcon]::Warning, [Cassia.RemoteMessageBoxDefaultButton]::Button2, [Cassia.RemoteMessageBoxOptions]::TopMost, [timespan]::FromSeconds($TimeOut), $true) $Target | Add-Member -Name Request -Value $Message -MemberType NoteProperty $target | Add-Member -Name Answer -Value $ClickOn -MemberType NoteProperty switch ($ClickOn){ 'Timeout' { Write-LogStep $Message,"L'utilisateur n'as pas repondu dans le [$timeOut Sec]" Error } Default { Write-LogStep $Message,"Reponce l'utilisateur [$ClickOn]" ok } } } catch { Write-LogStep "Question en session ",$PSBoundParameters Error Write-Host $_ -fore Red } $Target } # void MessageBox(string text) # void MessageBox(string text, string caption) # void MessageBox(string text, string caption, Cassia.RemoteMessageBoxIcon icon), # Cassia.RemoteMessageBoxResult MessageBox(string text, # string caption, # Cassia.RemoteMessageBoxButtons buttons, # Cassia.RemoteMessageBoxIcon icon, # Cassia.RemoteMessageBoxDefaultButton defaultButton, # Cassia.RemoteMessageBoxOptions options, # timespan timeout, # bool synchronous) # void ITerminalServicesSession.MessageBox(string text) # void ITerminalServicesSession.MessageBox(string text, string caption) # void ITerminalServicesSession.MessageBox(string text, string caption, Cassia.RemoteMessageBoxIcon icon) # # Cassia.RemoteMessageBoxResult ITerminalServicesSession.MessageBox('string text', # 'string caption', # [Cassia.RemoteMessageBoxButtons]::AbortRetryIgnore, # [Cassia.RemoteMessageBoxIcon]::Warning, # [Cassia.RemoteMessageBoxDefaultButton]::Button2, # [Cassia.RemoteMessageBoxOptions]::TopMost, # 3, # $true) } } # Export-ModuleMember -Function Convert-RdSession, Get-RdSession Write-LogStep 'Chargement du module ',$PSCommandPath ok |