Get-LoggedOnLocal now handles the situation when multiple SIDs are returned

Get-LoggedOnLocal turned into a filter and given additional error handling
Standardized tab/line spacing
Removed Invoke-PSLoggedOn
This commit is contained in:
Harmj0y 2016-05-22 14:07:37 -04:00
parent 2e6c9392c9
commit b568271d57
1 changed files with 37 additions and 105 deletions

View File

@ -8147,25 +8147,23 @@ filter Get-NetSession {
}
function Get-LoggedOnLocal {
filter Get-LoggedOnLocal {
<#
.SYNOPSIS
This function will query the HKU registry values to retrieve the local
logged on users SID and then attempt and reverse it.
Adapted technique from Sysinternal's PSLoggedOn script. Benefit over
using the NetWkstaUserEnum API (Get-NetLoggedon) of less user privileges
required (NetWkstaUserEnum requires remote admin access).
using the NetWkstaUserEnum API (Get-NetLoggedon) of less user privileges
required (NetWkstaUserEnum requires remote admin access).
Note: This function requires only domain user rights on the
machine you're enumerating.
Function: Get-LoggedOnLocal
Author: Matt Kelly, @BreakersAll;
Required Dependencies: @harmj0y's Powerview.
.PARAMETER ComputerName
machine you're enumerating, but remote registry must be enabled.
Function: Get-LoggedOnLocal
Author: Matt Kelly, @BreakersAll
.PARAMETER ComputerName
The ComputerName to query for active sessions.
@ -8187,105 +8185,39 @@ function Get-LoggedOnLocal {
param(
[Parameter(ValueFromPipeline=$True)]
[Alias('HostName')]
[String]
[Object[]]
[ValidateNotNullOrEmpty()]
$ComputerName = 'localhost'
)
begin {
if ($PSBoundParameters['Debug']) {
$DebugPreference = 'Continue'
# process multiple host object types from the pipeline
$ComputerName = Get-NameField -Object $ComputerName
try {
# retrieve HKU remote registry values
$Reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('Users', "$ComputerName")
# sort out bogus sid's like _class
$Reg.GetSubKeyNames() | Where-Object { $_ -match 'S-1-5-21-[0-9]+-[0-9]+-[0-9]+-[0-9]+$' } | ForEach-Object {
$UserName = Convert-SidToName $_
$Parts = $UserName.Split('\')
$UserDomain = $Null
$UserName = $Parts[-1]
if ($Parts.Length -eq 2) {
$UserDomain = $Parts[0]
}
$LocalLoggedOnUser = New-Object PSObject
$LocalLoggedOnUser | Add-Member Noteproperty 'ComputerName' "$ComputerName"
$LocalLoggedOnUser | Add-Member Noteproperty 'UserDomain' $UserDomain
$LocalLoggedOnUser | Add-Member Noteproperty 'UserName' $UserName
$LocalLoggedOnUser | Add-Member Noteproperty 'UserSID' $_
$LocalLoggedOnUser
}
}
process {
# process multiple host object types from the pipeline
$ComputerName = Get-NameField -Object $ComputerName
# retrieve HKU remote registry values
$Reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('Users', "$ComputerName")
# sort out bogus sid's like _class
$UserSID = $Reg.GetSubKeyNames() | ? { $_ -match 'S-1-5-21-[0-9]+-[0-9]+-[0-9]+-[0-9]+$' }
# if successful, convert sid and print output
if ($UserSID) {
$UserName = Convert-SidToName $UserSID
$LocalLoggedOnUser = New-Object PSObject
$LocalLoggedOnUser | Add-Member Noteproperty 'ComputerName' $ComputerName
$LocalLoggedOnUser | Add-Member Noteproperty 'UserName' $UserName
$LocalLoggedOnUser | Add-Member Noteproperty 'UserSID' $UserSID
$LocalLoggedOnUser
}
else {
Write-Debug "Could not retrieve values for $ComputerName"
}
Write-Debug "UserSIDs retrieved result: $Reg.GetSubKeyNames()"
}
}
function Invoke-PSLoggedOn {
<#
.SYNOPSIS
This function replicates PSLoggedOn functionality, and leverages
Get-NetSession (netsessionenum) and remote registry values.
Same actions as PSLoggedOn except in PowerShell.
Note: This function requires only domain user rights on the
machine you're enumerating.
Function: Invoke-PSLoggedOn
Author: Matt Kelly, @BreakersAll;
Required Dependencies: PowerView. PSv2
.PARAMETER ComputerName
The ComputerName to query for active sessions.
.EXAMPLE
PS C:\> Invoke-PSLoggedOn
Returns active sessions on the local host.
.EXAMPLE
PS C:\> Invoke-PSLoggedOn -ComputerName sqlserver
Returns active sessions on the 'sqlserver' host.
#>
[CmdletBinding()]
param(
[Parameter(ValueFromPipeline=$True)]
[Alias('HostName')]
[String]
$ComputerName = 'localhost'
)
begin {
if ($PSBoundParameters['Debug']) {
$DebugPreference = 'Continue'
}
}
process {
# process multiple host object types from the pipeline
$ComputerName = Get-NameField -Object $ComputerName
$LoggedOnLocal = Get-LoggedOnLocal $ComputerName
$NetSessionUsers = Get-NetSession $ComputerName
Write-Host "Users logged on locally to $ComputerName:"
$LoggedOnLocal
Write-Host ""
Write-Host "Users logged on via resource shares to $ComputerName:"
$NetSessionUsers
catch {
Write-Verbose "Error opening remote registry on '$ComputerName'"
}
}