Get-LoggedUser.psm1
|
<#
.SYNOPSIS Get logged users from computers .DESCRIPTION Get logged users from computers converting result from quser.exe Get-LoggedUser get direct from ComputerName and Get-ADLoggedUser check if computers exists in AD, get all computer objects from OU or get all Domain Controllers. .LINK .Linkedin: https://www.linkedin.com/in/erickvtorres/ .GitHub: https://github.com/erickvtorres .NOTES .Creator: Erick Torres do Vale .Contact: ericktorres@hotmail.com.br .Date: 2023-04-25 .LastUpdate: 2023-04-27 .Version: 0.0.1 .PARAMETER ComputerName Name of VMs or Computers to recover logged users, like computer01,computer02 .PARAMETER OU DistinguishedName from OU with desired servers or computers .PARAMETER DomainControllers Get all domain controllers from domain .EXAMPLE Get-LoggedUser Get-LoggedUser -ComputerName VMACHINE01,VMACHINE02,VMACHINE03 Get-ADLoggedUser -OU 'OU=Servers,DC=vkr,DC=inc' Get-ADLoggedUser -DomainControllers #> function Get-LoggedUser { [CmdletBinding(DefaultParameterSetName = 'ComputerName')] param ( [Parameter( Mandatory = $false, ParameterSetName = 'ComputerName' )] [array]$ComputerName ) begin { $defaultDisplaySet = 'ID', 'Username', 'SessionName', 'State' $defaultDisplayPropertySet = New-Object System.Management.Automation.PSPropertySet('DefaultDisplayPropertySet',[string[]]$defaultDisplaySet) $PSStandardMembers = [System.Management.Automation.PSMemberInfo[]]@($defaultDisplayPropertySet) $DateRegex = '[0-9]{2}\W{1}[0-9]{2}\W{1}[0-9]{4}\s{1}[0-9]{2}\W[0-9]{2}' if (-Not $ComputerName){$ComputerName = $env:COMPUTERNAME} } process { $ComputerName | ForEach-Object { $Users = quser /server:$_ 2>&1 if ($Users[0] -like 'Error*'){return} $Regex = $Users | Select-Object -Skip 1 | ForEach-Object -Process { $_ -replace '\s{2,}', ',' } $Regex | ForEach-Object { $Object = $_.Split(',') $Result = [PSCustomObject]@{ Username = $Object[0] -replace '>' -replace ' ' SessionName = if ($Object[1] -eq 'console' -or $Object[1] -like 'rdp-tcp*'){$Object[1]} else {'no-session'} ID = if ($Object[2] -match '[0-9]'){$Object[2]} else {$Object[1]} State = if ($Object[3] -match '[A-Za-z]'){$Object[3]} else {$Object[2]} IdleTime = if ($Object[4] -notmatch $DateRegex){$Object[4]} else {$Object[3]} LogonTime = if ($Object[5]) {$Object[5]} else {$Object[4]} } $Result.PSObject.TypeNames.Insert(0,'User.Information') $Result | Add-Member MemberSet PSStandardMembers $PSStandardMembers $Result } } } end { $List > $null } } function Get-ADLoggedUser { [CmdletBinding(DefaultParameterSetName = 'ComputerName')] param ( [Parameter( Mandatory = $false, ParameterSetName = 'ComputerName' )] [array]$ComputerName, [Parameter( Mandatory = $false, ParameterSetName = 'OU' )] [string]$OU, [Parameter( Mandatory = $false, ParameterSetName = 'DCs' )] [switch]$DomainControllers ) begin { $defaultDisplaySet = 'ID', 'Username', 'SessionName', 'State' $defaultDisplayPropertySet = New-Object System.Management.Automation.PSPropertySet('DefaultDisplayPropertySet',[string[]]$defaultDisplaySet) $PSStandardMembers = [System.Management.Automation.PSMemberInfo[]]@($defaultDisplayPropertySet) $DateRegex = '[0-9]{2}\W{1}[0-9]{2}\W{1}[0-9]{4}\s{1}[0-9]{2}\W[0-9]{2}' $Computers = New-Object -TypeName System.Collections.ArrayList switch ($PSBoundParameters.Keys) { ComputerName { try { $ComputerName | ForEach-Object { Get-ADComputer -Identity $_ | ForEach-Object { Write-Verbose "Computer: $($_.DistinguishedName)" [void]$Computers.Add($_.Name) } } } catch { Write-Warning $_.Exception.Message break } } OU { try { Get-ADComputer -Filter {Enabled -eq $true} -SearchBase $OU | ForEach-Object { Write-Verbose "Computer: $($_.DistinguishedName)" [void]$Computers.Add($_.Name) } } catch { Write-Warning $_.Exception.Message break } } DomainControllers { try { Get-ADDomainController -Filter * | ForEach-Object { Write-Verbose "Computer: $($_.ComputerObjectDN)" [void]$Computers.Add($_.Name) } } catch { Write-Warning $_.Exception.Message break } } Default { break } } } process { $Computers | ForEach-Object { $Users = quser /server:$_ 2>&1 if ($Users[0] -like 'Error*'){return} $Regex = $Users | Select-Object -Skip 1 | ForEach-Object -Process { $_ -replace '\s{2,}', ',' } $Regex | ForEach-Object { $Object = $_.Split(',') $Result = [PSCustomObject]@{ Username = $Object[0] -replace '>' -replace ' ' SessionName = if ($Object[1] -eq 'console' -or $Object[1] -like 'rdp-tcp*'){$Object[1]} else {'no-session'} ID = if ($Object[2] -match '[0-9]'){$Object[2]} else {$Object[1]} State = if ($Object[3] -match '[A-Za-z]'){$Object[3]} else {$Object[2]} IdleTime = if ($Object[4] -notmatch $DateRegex){$Object[4]} else {$Object[3]} LogonTime = if ($Object[5]) {$Object[5]} else {$Object[4]} } $Result.PSObject.TypeNames.Insert(0,'User.Information') $Result | Add-Member MemberSet PSStandardMembers $PSStandardMembers $Result } } } end { $Computers > $null } } |