none
Ist ein Benutzer per RemoteDesktop an einem PC angemeldet? RRS feed

  • Frage

  • Hallo zusammen,

    wie der Titel schon sagt würde ich gern per PowerShell abfragen ob an einem (oder mehreren) PCs im Netzwerk ein Benutzer (wer ist mir egal, nur das ob ist Wichtig) per RemoteDesktop angemeldet ist.

    Wenn keiner angemeldet ist würde ich dann nämlich gerne automatisch per PowerShell ein paar Tasks starten können (z.B. einen Reboot durchführen).

    Ich habe es schon mit Get-WmiObject -Class Win32_ComputerSystem versucht, allerdings zeigt es mit den per RemoteDesktop angemeldeten Benutzer nicht an.

    Vorab vielen Dank für Hilfe

    Viele Grüße


    Donnerstag, 23. Januar 2014 14:29

Antworten

  • Du musst die Terminal Services (TS) Sessions auslesen.
    Remote Desktop benutzt auch die Terminal Services!

    Dies geht mit dieser Funktion:

    Function Get-WMILoggedOnUser {
    <#
    .SYNOPSIS
        Function to get all logged on sessions (numbers) and coresponding users (domain name) on a local or remote system with WMI
    	
    .DESCRIPTION
        Function to get all logged on sessions (numbers) and coresponding users (domain name) on a local or remote system with WMI
    	
    	Gets the Win32_LogonSession and the associated Win32_LoggedOnUser information from WMI.
    	Matches the user to the session by sessionid
    	Creates a link between the LogType number to LogonTypeName name for the session logon type
    	
    	Returns an PSCustomObject:
    		User properties: Domain,Name and SID
    		UserSession properties: StartTime,LogonID,LogonType,LogonTypeName and the ComputerName
    		
    .PARAMETER ComputerName
    	Specifies the computer against which you want to run the management operation.
    	The value can be a fully qualified domain name, a NetBIOS name, or an IP address.
    	Use the local computer name, use localhost, or use a dot (.) to specify the local computer.
    	The local computer is the default. When the remote computer is in a different domain from the user,
    	you must use a fully qualified domain name. This parameter can also be piped to the cmdlet.
    	
    .PARAMETER Logontype
    	
    	Parameter to select the returned logontype(s)
    	
    	See MSDN documentation for the WMI Win32_LogonSession class Property Logontype
    	
    	Win32_LogonSession.Logontype is Numeric value that indicates the type of logon session.
    
    	0	Used only by the System account.
    
    	2	Interactive
    		Intended for users who are interactively using the machine, such as a user
    		being logged on by a terminal server, remote shell, or similar process.
    
    	3	Network
    		Intended for high-performance servers to authenticate clear text passwords.
    		LogonUser does not cache credentials for this logon type.
    
    	4	Batch
    		Intended for batch servers, where processes can be executed on behalf of a user
    		without their direct intervention; or for higher performance servers that process many
    		clear-text authentication attempts at a time, such as mail or web servers. LogonUser
    		does not cache credentials for this logon type.
    
    	5	Service
    		Indicates a service-type logon. The account provided must have the service privilege enabled.
    
    	6	Proxy
    		Indicates a proxy-type logon.
    
    	7	Unlock
    		This logon type is intended for GINA DLLs logging on users who are interactively
    		using the machine. This logon type allows a unique audit record to be generated
    		that shows when the workstation was unlocked.
    
    	8	NetworkCleartext
    		Windows Server 2003 and Windows XP:  Preserves the name and password in the authentication packages,
    		allowing the server to make connections to other network servers while impersonating the client.
    		This allows a server to accept clear text credentials from a client, call LogonUser, verify that
    		the user can access the system across the network, and still communicate with other servers.
    
    	9	NewCredentials
    		Windows Server 2003 and Windows XP:  Allows the caller to clone its current
    		token and specify new credentials for outbound connections. The new logon session
    		has the same local identify, but uses different credentials for other network connections.
    
    	10	RemoteInteractive
    		Terminal Services session that is both remote and interactive.
    
    	11	CachedInteractive
    		Attempt cached credentials without accessing the network.
    
    	12	CachedRemoteInteractive
    		Same as RemoteInteractive. This is used for internal auditing.
    
    	13	CachedUnlock
    		Workstation logon.
    		
    .EXAMPLE
        Get-WMILoggedOnUser
    	
    	Returns all types of logged on User sessions on the local machine (computer)
    	
    .EXAMPLE
        Get-WMILoggedOnUser -Computername 'localhost'  -LogonType 'All'
    	
    	Same as example 1: Returns all types of logged on User sessions on the local machine (computer)
    	
    .EXAMPLE
        Get-WMILoggedOnUser -Computername 'Server1','Server2' -LogonType 'Interactive'
    	
    	Returns only logged on Users with logon type of 'Interactive' (number 2)
    	
    .NOTES
        Author: Peter Kriegel
        Version 1.0.0
        12.July.2013
    #>
    
        [Cmdletbinding()]
        param (
            [Parameter(Position=0,ValueFromPipeline=$True)]
            [String[]]$Computername = $ENV:COMPUTERNAME,
    		
    		[Parameter(Position=1)]
    		[ValidateSet('0','LocalSystem','2','Interactive','3','Network','4','Batch','5',
    		'Service','6','Proxy','7','Unlock','8','NetworkCleartext','9','NewCredentials',
    		'10','RemoteInteractive','11','CachedInteractive','12','CachedRemoteInteractive',
    		'13','CachedUnlock','All')]
    		[String[]]$LogonType = @('0','2','3','4','5','6','7','8','9','10','11','12','13') # All
        )
    
        Begin{
                # define LogOnType hashtable for to convert Numbers into Text
                $HashLogonType = @{ 
                    '0'='LocalSystem' 
                    '2'='Interactive'
                    '3'='Network'
                    '4'='Batch'
                    '5'='Service'
                    '6'='Proxy'
                    '7'='Unlock'
                    '8'='NetworkCleartext'
                    '9'='NewCredentials'
                    '10'='RemoteInteractive'
                    '11'='CachedInteractive'
                    '12'='CachedRemoteInteractive'
                    '13'='CachedUnlock'
                }
                
        } # end Begin block
    
        Process {
        
            ForEach($CurComputerName in $ComputerName) {
            
                $LogonSessions = Get-WmiObject Win32_LogonSession -ComputerName $CurComputerName
    
                ForEach($LogonSession in $LogonSessions) {
                    
                    $WMILoggedOnUser = Get-WmiObject -ErrorAction SilentlyContinue -Query "Associators of {Win32_LogonSession.LogonId=$($LogonSession.LogonId)} Where AssocClass=Win32_LoggedOnUser Role=Dependent" -ComputerName $CurComputerName
                    
                    If(-not $WMILoggedOnUser) {continue}
                     
                    $LoggedOnUser = $WMILoggedOnUser | Select-Object Domain,Name,SID,StartTime,LogonID,LogonType,LogonTypeName,ComputerName
                    
                    $LoggedOnUser.StartTime = [Management.ManagementDateTimeConverter]::ToDateTime($LogonSession.starttime)
                    $LoggedOnUser.LogonID = $LogonSession.LogonID
                    $LoggedOnUser.LogonType = $LogonSession.logontype
                    $LoggedOnUser.LogonTypeName = $HashLogonType[[String]$LogonSession.logontype]
                    $LoggedOnUser.ComputerName = $CurComputerName
                    
    				# Filter selected LogonTypes to report
    				If($LogonType -contains [String]$LoggedOnUser.LogonType -or $LogonType -contains $LoggedOnUser.LogonTypeName) {
    					# return result object
    					$LoggedOnUser
    				}
                } # end  ForEach $LogonSession
                
            }  # end ForEach $Computer 
             
        } # end process block
        End {}
    
    }
    
    # Beispiel alle eingeloggte User auf diesem Computer auslesen
    Get-WMILoggedOnUser
    
    
    # Terminal Services session
    # Beispiel alle Remote eingeloggten User auf diesem Computer auslesen
    Get-WMILoggedOnUser -LogonType 'RemoteInteractive'

    Dieses Modul kann dir da auch weiterhelfen: http://archive.msdn.microsoft.com/PSTerminalServices

    Get-TSSession -ComputerName $ServerName
    Oder:

    Windows Server 2012 und das RDS Modul:

    http://www.virtualizationadmin.com/articles-tutorials/vdi-articles/general/using-powershell-control-rds-windows-server-2012.html


    PowerShell Artikel, Buchtipps und kostenlose PowerShell Tutorials + E-Books
    auf der deutschsprachigen PowerShell Community

    Mein 21 Teiliger PowerShell Video Grundlehrgang
    Deutsche PowerShell Videos auf Youtube
    Folge mir auf:
    Twitter | Facebook | Google+

    Donnerstag, 23. Januar 2014 15:48

Alle Antworten

  • Hallo,

    das kannst Du z.B.: mit folgendem DOS-Comand machen, was natuerlich auch in de PowerShell geht.

    qwinsta /Server:localhost

    localhost durch den Servernamen ersetzen.

    Beste Gruesse
    brima

    Donnerstag, 23. Januar 2014 15:47
  • Du musst die Terminal Services (TS) Sessions auslesen.
    Remote Desktop benutzt auch die Terminal Services!

    Dies geht mit dieser Funktion:

    Function Get-WMILoggedOnUser {
    <#
    .SYNOPSIS
        Function to get all logged on sessions (numbers) and coresponding users (domain name) on a local or remote system with WMI
    	
    .DESCRIPTION
        Function to get all logged on sessions (numbers) and coresponding users (domain name) on a local or remote system with WMI
    	
    	Gets the Win32_LogonSession and the associated Win32_LoggedOnUser information from WMI.
    	Matches the user to the session by sessionid
    	Creates a link between the LogType number to LogonTypeName name for the session logon type
    	
    	Returns an PSCustomObject:
    		User properties: Domain,Name and SID
    		UserSession properties: StartTime,LogonID,LogonType,LogonTypeName and the ComputerName
    		
    .PARAMETER ComputerName
    	Specifies the computer against which you want to run the management operation.
    	The value can be a fully qualified domain name, a NetBIOS name, or an IP address.
    	Use the local computer name, use localhost, or use a dot (.) to specify the local computer.
    	The local computer is the default. When the remote computer is in a different domain from the user,
    	you must use a fully qualified domain name. This parameter can also be piped to the cmdlet.
    	
    .PARAMETER Logontype
    	
    	Parameter to select the returned logontype(s)
    	
    	See MSDN documentation for the WMI Win32_LogonSession class Property Logontype
    	
    	Win32_LogonSession.Logontype is Numeric value that indicates the type of logon session.
    
    	0	Used only by the System account.
    
    	2	Interactive
    		Intended for users who are interactively using the machine, such as a user
    		being logged on by a terminal server, remote shell, or similar process.
    
    	3	Network
    		Intended for high-performance servers to authenticate clear text passwords.
    		LogonUser does not cache credentials for this logon type.
    
    	4	Batch
    		Intended for batch servers, where processes can be executed on behalf of a user
    		without their direct intervention; or for higher performance servers that process many
    		clear-text authentication attempts at a time, such as mail or web servers. LogonUser
    		does not cache credentials for this logon type.
    
    	5	Service
    		Indicates a service-type logon. The account provided must have the service privilege enabled.
    
    	6	Proxy
    		Indicates a proxy-type logon.
    
    	7	Unlock
    		This logon type is intended for GINA DLLs logging on users who are interactively
    		using the machine. This logon type allows a unique audit record to be generated
    		that shows when the workstation was unlocked.
    
    	8	NetworkCleartext
    		Windows Server 2003 and Windows XP:  Preserves the name and password in the authentication packages,
    		allowing the server to make connections to other network servers while impersonating the client.
    		This allows a server to accept clear text credentials from a client, call LogonUser, verify that
    		the user can access the system across the network, and still communicate with other servers.
    
    	9	NewCredentials
    		Windows Server 2003 and Windows XP:  Allows the caller to clone its current
    		token and specify new credentials for outbound connections. The new logon session
    		has the same local identify, but uses different credentials for other network connections.
    
    	10	RemoteInteractive
    		Terminal Services session that is both remote and interactive.
    
    	11	CachedInteractive
    		Attempt cached credentials without accessing the network.
    
    	12	CachedRemoteInteractive
    		Same as RemoteInteractive. This is used for internal auditing.
    
    	13	CachedUnlock
    		Workstation logon.
    		
    .EXAMPLE
        Get-WMILoggedOnUser
    	
    	Returns all types of logged on User sessions on the local machine (computer)
    	
    .EXAMPLE
        Get-WMILoggedOnUser -Computername 'localhost'  -LogonType 'All'
    	
    	Same as example 1: Returns all types of logged on User sessions on the local machine (computer)
    	
    .EXAMPLE
        Get-WMILoggedOnUser -Computername 'Server1','Server2' -LogonType 'Interactive'
    	
    	Returns only logged on Users with logon type of 'Interactive' (number 2)
    	
    .NOTES
        Author: Peter Kriegel
        Version 1.0.0
        12.July.2013
    #>
    
        [Cmdletbinding()]
        param (
            [Parameter(Position=0,ValueFromPipeline=$True)]
            [String[]]$Computername = $ENV:COMPUTERNAME,
    		
    		[Parameter(Position=1)]
    		[ValidateSet('0','LocalSystem','2','Interactive','3','Network','4','Batch','5',
    		'Service','6','Proxy','7','Unlock','8','NetworkCleartext','9','NewCredentials',
    		'10','RemoteInteractive','11','CachedInteractive','12','CachedRemoteInteractive',
    		'13','CachedUnlock','All')]
    		[String[]]$LogonType = @('0','2','3','4','5','6','7','8','9','10','11','12','13') # All
        )
    
        Begin{
                # define LogOnType hashtable for to convert Numbers into Text
                $HashLogonType = @{ 
                    '0'='LocalSystem' 
                    '2'='Interactive'
                    '3'='Network'
                    '4'='Batch'
                    '5'='Service'
                    '6'='Proxy'
                    '7'='Unlock'
                    '8'='NetworkCleartext'
                    '9'='NewCredentials'
                    '10'='RemoteInteractive'
                    '11'='CachedInteractive'
                    '12'='CachedRemoteInteractive'
                    '13'='CachedUnlock'
                }
                
        } # end Begin block
    
        Process {
        
            ForEach($CurComputerName in $ComputerName) {
            
                $LogonSessions = Get-WmiObject Win32_LogonSession -ComputerName $CurComputerName
    
                ForEach($LogonSession in $LogonSessions) {
                    
                    $WMILoggedOnUser = Get-WmiObject -ErrorAction SilentlyContinue -Query "Associators of {Win32_LogonSession.LogonId=$($LogonSession.LogonId)} Where AssocClass=Win32_LoggedOnUser Role=Dependent" -ComputerName $CurComputerName
                    
                    If(-not $WMILoggedOnUser) {continue}
                     
                    $LoggedOnUser = $WMILoggedOnUser | Select-Object Domain,Name,SID,StartTime,LogonID,LogonType,LogonTypeName,ComputerName
                    
                    $LoggedOnUser.StartTime = [Management.ManagementDateTimeConverter]::ToDateTime($LogonSession.starttime)
                    $LoggedOnUser.LogonID = $LogonSession.LogonID
                    $LoggedOnUser.LogonType = $LogonSession.logontype
                    $LoggedOnUser.LogonTypeName = $HashLogonType[[String]$LogonSession.logontype]
                    $LoggedOnUser.ComputerName = $CurComputerName
                    
    				# Filter selected LogonTypes to report
    				If($LogonType -contains [String]$LoggedOnUser.LogonType -or $LogonType -contains $LoggedOnUser.LogonTypeName) {
    					# return result object
    					$LoggedOnUser
    				}
                } # end  ForEach $LogonSession
                
            }  # end ForEach $Computer 
             
        } # end process block
        End {}
    
    }
    
    # Beispiel alle eingeloggte User auf diesem Computer auslesen
    Get-WMILoggedOnUser
    
    
    # Terminal Services session
    # Beispiel alle Remote eingeloggten User auf diesem Computer auslesen
    Get-WMILoggedOnUser -LogonType 'RemoteInteractive'

    Dieses Modul kann dir da auch weiterhelfen: http://archive.msdn.microsoft.com/PSTerminalServices

    Get-TSSession -ComputerName $ServerName
    Oder:

    Windows Server 2012 und das RDS Modul:

    http://www.virtualizationadmin.com/articles-tutorials/vdi-articles/general/using-powershell-control-rds-windows-server-2012.html


    PowerShell Artikel, Buchtipps und kostenlose PowerShell Tutorials + E-Books
    auf der deutschsprachigen PowerShell Community

    Mein 21 Teiliger PowerShell Video Grundlehrgang
    Deutsche PowerShell Videos auf Youtube
    Folge mir auf:
    Twitter | Facebook | Google+

    Donnerstag, 23. Januar 2014 15:48
  • Dazu muss ich leider gleich eine doofe Frage stellen, wie nutze ich die Funktion Get-WMILoggedOnUser in PowerShell?
    Donnerstag, 23. Januar 2014 16:03
  • Hallo,

    die PowerShell hat eine ausfuehrliche Hilfe, wie man eine Funktion benutzt kannst Du so nachlesen.

    Zudem gibt es direkt in der Funktion von Peter auch die Hilfe, such mal in der Funktion nach EXAMPLE, und schon hast du Beispiele wie genau diese Funktion aufzurufen ist.

    get-help about_functions


    Beste Gruesse
    brima

    • Bearbeitet brima Donnerstag, 23. Januar 2014 16:20
    Donnerstag, 23. Januar 2014 16:18
  • Ich habe doch extra unten im Code noch 2 Beispiele angefügt!

    Annsonnsten siehe in den Examples im Code wie Brima schon sagte.

    Der Funktionscode muss vor dem 1. Aufruf der Funktion stehen!


    PowerShell Artikel, Buchtipps und kostenlose PowerShell Tutorials + E-Books
    auf der deutschsprachigen PowerShell Community

    Mein 21 Teiliger PowerShell Video Grundlehrgang
    Deutsche PowerShell Videos auf Youtube
    Folge mir auf:
    Twitter | Facebook | Google+

    Donnerstag, 23. Januar 2014 19:44
  • Danke erstmal für den Code!

    Sorry, ich stand vorhin etwas auf dem Schlauch, PowerShell und ich versuchen gerade erst Freunde zu werden :-)

    Ich habe jetzt mal folgendes mit deinem Code gebastelt, das funktioniert auch auf einem Win7 PC. Allerdings gibt ein 2012R2 aus das kein User angemeldet ist, obwohl das der Fall ist (Win8 hab ich noch nicht probieren können)

    $Ergebnis = Get-WMILoggedOnUser -LogonType 'RemoteInteractive' -Computername 'computer'
    $Ergebnis
    if(-NOT $Ergebnis){echo "Kein User Remote angemeldet!"}
    Oder mache ich hier einen Denkfehler?

    Donnerstag, 23. Januar 2014 20:20
  • Hallo,

    ein gute Idee waere es z.B: den Server dann auch mal auf einem anderen Weg zu befragen, z.B.: wie oben schon vorgeschlagen mit qwinsta.

    Hier findest Du im uebrigen 2 PowerShellfunktionen (siehe die Beschreibung dort) die die TextAusgabe von QWINSA/RWINSTA als Objekte zurueck liefern.

    http://gallery.technet.microsoft.com/Get-RDPSession-Remove-7546bf39

    So kann man versuchen einzugrenzen, ob der getestete W2K12R2 Server generell Probleme hat, oder Code auf das OS angepasst werden muss usw.

    Eine andere Moeglichkeit fuer den Check waere folgendes DOS Command.

    query session -?

    Beste Gruesse
    brima

    • Als Antwort vorgeschlagen Alex Pitulice Donnerstag, 30. Januar 2014 10:16
    Donnerstag, 23. Januar 2014 21:04
  • Windows 8 und Server 2012 haben einen "besseren" Remote Desktop.

    Da musst du eventuell 2 Techniken Kombinieren.

    Ich habe keinen Server 2012,  kann das nicht testen!

    $Ergebnis = Get-WMILoggedOnUser -LogonType 'RemoteInteractive' -Computername 'computer' If(-NOT $Ergebnis){ # suchen ob das Modul vorhanden ist (Server 2012) If((Get-Module 'RemoteDesktop') -or (Get-Module -ListAvailable | Where-Object {$_.Name -eq 'RemoteDesktop'} )) { # Modul wurde gefunden wir importieren es Import-Module 'RemoteDesktop'

    # Get-RDUserSession aus dem Modul benutzen $Ergebnis = Get-RDUserSession } } Else { "Kein User gefunden!" } $Ergebnis

    Die Dokumentation zu dem Modul findest du hier :

    http://technet.microsoft.com/en-us/library/jj215451.aspx


    PowerShell Artikel, Buchtipps und kostenlose PowerShell Tutorials + E-Books
    auf der deutschsprachigen PowerShell Community

    Mein 21 Teiliger PowerShell Video Grundlehrgang
    Deutsche PowerShell Videos auf Youtube
    Folge mir auf:
    Twitter | Facebook | Google+


    • Bearbeitet Peter Kriegel Freitag, 24. Januar 2014 06:52
    • Als Antwort vorgeschlagen Alex Pitulice Donnerstag, 30. Januar 2014 10:16
    Freitag, 24. Januar 2014 06:44
  • Donnerstag, 30. Januar 2014 10:17
  • Hallo Alex,

    ich konnte es leider auch noch nicht richtig testen, daher kann ich nicht sagen ob es funktioniert.

    Grüße

    Rolf

    Donnerstag, 30. Januar 2014 10:54