Powershell Script Angemeldete User und ClientPC
Hallo zusammen,
ich habe online folgendes Script gefunden:
Das Script kommt von hier:
https://web.archive.org/web/20210118231433/https://gallery.technet.micro ...
Dieses Script gibt an welche User auf den vorher genannten Servern angemeldet bzw getrennt sind.
Das funktioniert auch super, aber ich würde gerne noch sehen wie der Rechner heißt, von dem der User kommt...
Hier ist das "ComputerName" leider nur der Server auf dem der User aktuell angemeldet ist.
Kannman dieses Script dazu unkompliziert anpassen ?
VG
ich habe online folgendes Script gefunden:
<#
.Synopsis
Queries a computer to check for interactive sessions
.DESCRIPTION
This script takes the output from the quser program and parses this to PowerShell objects
.NOTES
Name: Get-LoggedOnUser
Author: Jaap Brasser
Version: 1.2.1
DateUpdated: 2015-09-23
.LINK
http://www.jaapbrasser.com
.PARAMETER ComputerName
The string or array of string for which a query will be executed
.EXAMPLE
.\Get-LoggedOnUser.ps1 -ComputerName server01,server02
Description:
Will display the session information on server01 and server02
.EXAMPLE
'server01','server02' | .\Get-LoggedOnUser.ps1
Description:
Will display the session information on server01 and server02
#>
param(
[CmdletBinding()]
[Parameter(ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true)]
[string[]]$ComputerName = 'localhost'
)
begin {
$ErrorActionPreference = 'Stop'
}
process {
foreach ($Computer in $ComputerName) {
try {
quser /server:$Computer 2>&1 | Select-Object -Skip 1 | ForEach-Object {
$CurrentLine = $_.Trim() -Replace '\s+',' ' -Split '\s'
$HashProps = @{
UserName = $CurrentLine
ComputerName = $Computer
}
# If session is disconnected different fields will be selected
if ($CurrentLine[2] -eq 'Disc') {
$HashProps.SessionName = $null
$HashProps.Id = $CurrentLine[1]
$HashProps.State = $CurrentLine[2]
$HashProps.IdleTime = $CurrentLine[3]
$HashProps.LogonTime = $CurrentLine[4..6] -join ' '
$HashProps.LogonTime = $CurrentLine[4..($CurrentLine.GetUpperBound(0))] -join ' '
} else {
$HashProps.SessionName = $CurrentLine[1]
$HashProps.Id = $CurrentLine[2]
$HashProps.State = $CurrentLine[3]
$HashProps.IdleTime = $CurrentLine[4]
$HashProps.LogonTime = $CurrentLine[5..($CurrentLine.GetUpperBound(0))] -join ' '
}
New-Object -TypeName PSCustomObject -Property $HashProps |
Select-Object -Property UserName,ComputerName,State
}
} catch {
New-Object -TypeName PSCustomObject -Property @{
ComputerName = $Computer
Error = $_.Exception.Message
} | Select-Object -Property UserName,ComputerName,State
}
}
}
Das Script kommt von hier:
https://web.archive.org/web/20210118231433/https://gallery.technet.micro ...
Dieses Script gibt an welche User auf den vorher genannten Servern angemeldet bzw getrennt sind.
Das funktioniert auch super, aber ich würde gerne noch sehen wie der Rechner heißt, von dem der User kommt...
Hier ist das "ComputerName" leider nur der Server auf dem der User aktuell angemeldet ist.
Kannman dieses Script dazu unkompliziert anpassen ?
VG
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 1719323925
Url: https://administrator.de/contentid/1719323925
Ausgedruckt am: 21.11.2024 um 23:11 Uhr
7 Kommentare
Neuester Kommentar
Moin,
das Script "mal eben kurz"/unkompliziert zu erweitern, ist nicht möglich, weil quser.exe keine Informationen zum Quell-Host liefert...
Vielleicht findet sich ja die ein oder andere Person, welche das Script um mehr als das Parsen des outputs ergänzt.
Viel Erfolg!
schleeke
das Script "mal eben kurz"/unkompliziert zu erweitern, ist nicht möglich, weil quser.exe keine Informationen zum Quell-Host liefert...
Vielleicht findet sich ja die ein oder andere Person, welche das Script um mehr als das Parsen des outputs ergänzt.
Viel Erfolg!
schleeke
Servus,
kann man mit dem String-Geparse von quser/qwinsta/query user &co. machen, aber wenn sich etwas mit nativen System-Funktionen auslesen bevorzuge ich das dann doch
Grüße Uwe
kann man mit dem String-Geparse von quser/qwinsta/query user &co. machen, aber wenn sich etwas mit nativen System-Funktionen auslesen bevorzuge ich das dann doch
param(
[parameter(mandatory=$true)][ValidateNotNullOrEmpty()][string[]]$computers
)
Add-Type '
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Security;
using System.Net;
namespace WTS {
public static class Sessions {
public enum WTS_CONNECTSTATE_CLASS {
WTSActive,
WTSConnected,
WTSConnectQuery,
WTSShadow,
WTSDisconnected,
WTSIdle,
WTSListen,
WTSReset,
WTSDown,
WTSInit
}
public enum WTS_INFO_CLASS
{
WTSInitialProgram,
WTSApplicationName,
WTSWorkingDirectory,
WTSOEMId,
WTSSessionId,
WTSUserName,
WTSWinStationName,
WTSDomainName,
WTSConnectState,
WTSClientBuildNumber,
WTSClientName,
WTSClientDirectory,
WTSClientProductId,
WTSClientHardwareId,
WTSClientAddress,
WTSClientDisplay,
WTSClientProtocolType,
WTSIdleTime,
WTSLogonTime,
WTSIncomingBytes,
WTSOutgoingBytes,
WTSIncomingFrames,
WTSOutgoingFrames,
WTSClientInfo,
WTSSessionInfo
}
[StructLayout(LayoutKind.Sequential)]
private struct WTS_CLIENT_ADDRESS
{
public uint AddressFamily;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[] Address;
}
[StructLayout(LayoutKind.Sequential)]
private struct WTS_SESSION_INFO_1 {
public Int32 ExecEnvId;
public WTS_CONNECTSTATE_CLASS State;
public Int32 SessionId;
[MarshalAs(UnmanagedType.LPStr)]
public String pSessionName;
[MarshalAs(UnmanagedType.LPStr)]
public String pHostName;
[MarshalAs(UnmanagedType.LPStr)]
public String pUserName;
[MarshalAs(UnmanagedType.LPStr)]
public String pDomainName;
[MarshalAs(UnmanagedType.LPStr)]
public String pFarmName;
}
[StructLayout(LayoutKind.Sequential)]
public struct WTS_CLIENT_DISPLAY {
public int HorizontalResolution;
public int VerticalResolution;
public int ColorDepth;
}
[DllImport("wtsapi32.dll", SetLastError = true)]
static extern IntPtr WTSOpenServer([MarshalAs(UnmanagedType.LPStr)] String pServerName);
[DllImport("wtsapi32.dll")]
static extern void WTSCloseServer(IntPtr hServer);
[DllImport("Wtsapi32.dll", SetLastError = true), SuppressUnmanagedCodeSecurity]
static extern int WTSEnumerateSessionsEx(IntPtr hServer, ref int pLevel, int Filter, ref IntPtr ppSessionInfo, ref int pCount);
[DllImport("wtsapi32.dll", SetLastError = true)]
static extern bool WTSQuerySessionInformation(IntPtr hServer, int sessionId, WTS_INFO_CLASS wtsInfoClass, out IntPtr ppBuffer, out int pBytesReturned);
[DllImport("wtsapi32.dll")]
static extern void WTSFreeMemory(IntPtr pMemory);
public class TerminalSession {
public int SessionId;
public WTS_CONNECTSTATE_CLASS SessionState;
public string Host;
public string SessionName;
public string UserName;
public object RemoteHost;
public string DomainName;
public string FarmName;
public int ClientHorizontalResolution;
public int ClientVerticalResolution;
public string ClientColorDepth;
}
public static List<TerminalSession> GetTSSessions(string Server = "") {
IntPtr server = IntPtr.Zero;
List<TerminalSession> result = new List<TerminalSession>();
if (Server != "") {
server = WTSOpenServer(Server);
}
try {
IntPtr ppSessionInfo = IntPtr.Zero;
Int32 count = 0;
Int32 pLevel = 1;
Int32 retval = WTSEnumerateSessionsEx(server, ref pLevel, 0, ref ppSessionInfo, ref count);
Int32 dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO_1));
Int64 current = (Int64)ppSessionInfo;
IntPtr buffer;
int strLen;
Hashtable colordepths = new Hashtable() {{ 1, "4bit"},{ 2, "8bit"},{ 4, "16bit"},{ 8, "24bit"},{ 16, "15bit"},{ 24, "24bit"},{ 32, "32bit"}};
if (retval != 0) {
for (int i = 0; i < count; i++) {
WTS_SESSION_INFO_1 si = (WTS_SESSION_INFO_1)Marshal.PtrToStructure((IntPtr)current, typeof(WTS_SESSION_INFO_1));
current += dataSize;
// get remote host information
object remotehost = null;
if (WTSQuerySessionInformation(server,si.SessionId ,WTS_INFO_CLASS.WTSClientAddress, out buffer, out strLen) && strLen > 1){
WTS_CLIENT_ADDRESS c_address = (WTS_CLIENT_ADDRESS)Marshal.PtrToStructure(buffer, typeof(WTS_CLIENT_ADDRESS));
if (c_address.AddressFamily == 2 && c_address.Address[2] != 0){
// AF_INET (IPv4 address)
remotehost = new IPAddress(new byte[] {c_address.Address[2],c_address.Address[3],c_address.Address[4],c_address.Address[5]});
} else if (c_address.AddressFamily == 23){
// AF_INET6 (IPv6 address)
byte[] bv6 = new byte[16];
Array.Copy(c_address.Address,2,bv6,0,16);
remotehost = new IPAddress(bv6);
} else {
remotehost = new IPAddress(new byte[] {0,0,0,0});
}
WTSFreeMemory(buffer);
}
// get remote display information
WTS_CLIENT_DISPLAY oClientDisplay = new WTS_CLIENT_DISPLAY();
if (WTSQuerySessionInformation(server,si.SessionId ,WTS_INFO_CLASS.WTSClientDisplay, out buffer, out strLen) && strLen > 1){
oClientDisplay = (WTS_CLIENT_DISPLAY)Marshal.PtrToStructure(buffer, oClientDisplay.GetType());
WTSFreeMemory(buffer);
}
result.Add(new TerminalSession() {
SessionId = si.SessionId,
SessionState = si.State,
SessionName = si.pSessionName,
Host = Server,
RemoteHost = remotehost,
UserName = si.pUserName,
DomainName = si.pDomainName,
FarmName = si.pFarmName,
ClientHorizontalResolution = oClientDisplay.HorizontalResolution,
ClientVerticalResolution = oClientDisplay.VerticalResolution,
ClientColorDepth = (string)colordepths[oClientDisplay.ColorDepth]
});
}
WTSFreeMemory(ppSessionInfo);
}
}catch(Exception ex) {
throw new Exception(ex.Message);
} finally {
WTSCloseServer(server);
}
return result;
}
}
}
'
$computers | %{[WTS.Sessions]::GetTSSessions($_) | select Host,SessionId,SessionState,Sessionname,DomainName,Username,RemoteHost}
Sweet! 😁
Zitat von @geloescht:
Cool, vielen Dank schonmal.
Aber... :D Die Remotehosts nutzen mir leider als IP Adressen gar nichts, ich bräuchte hier tatsächlich den Hostname.
Ist das auch möglich ?
Cool, vielen Dank schonmal.
Aber... :D Die Remotehosts nutzen mir leider als IP Adressen gar nichts, ich bräuchte hier tatsächlich den Hostname.
Ist das auch möglich ?
Klar löse den Hostname einfach reverse über den Pointer Eintrag deines DNS-Servers auf
[System.Net.Dns]::Resolve('1.1.1.1').Hostname
Für das obige Skript ändere die letzte Zeile in
$computers | %{[WTS.Sessions]::GetTSSessions($_) | select Host,SessionId,SessionState,Sessionname,DomainName,Username,@{n='RemoteHost';e={if($_.RemoteHost -ne $null){[System.Net.Dns]::Resolve($_.RemoteHost).Hostname}}}}