QuestADTools.psm1
<#
=========================================================================== Created with: SAPIEN Technologies, Inc., PowerShell Studio 2024 v5.8.238 Created on: 3/11/2024 7:33 PM Created by: Gary Cook Organization: Quest Filename: QuestADTools.psm1 ------------------------------------------------------------------------- Module Name: QuestADTools =========================================================================== #> function Write-HelloWorld { Write-Host "Hello World" } function Get-DomainsinForest ($ForestName, $Credential, $TargetServer) { $Domains = Get-ADForest -Identity $ForestName -Server $TargetServer -Credential $Credential return $Domains.Domains } function Get-AllDomainControllers ($DomainName,$Credential) { #find first DC for domain $FDC = Get-ADDomainController -DomainName $DomainName -Discover $allDomainControllers = Get-ADDomainController -Server $FDC -Filter * -Credential $Credential return $allDomainControllers } function Verify-DomainControllerIP ($DomainController, $IP) { #test that DNS agrees with AD IP $DNSIP = Resolve-DnsName -Name $DomainController -Type A $Match = $false foreach ($Address in $DNSIP) { if ($Address.IPAddress -eq $IP) { $Match = $true } } $Result = New-Object System.Management.Automation.PSObject $Result | Add-Member -MemberType NoteProperty -Name Match -Value $Match $Result | Add-Member -MemberType NoteProperty -Name DNSIP -Value $DNSIP.IPAddress #test to see if Computer responds to connection on all IP addresses $TempResult = @() foreach ($Address in $DNSIP.IPAddress) { $IPResult = New-Object System.Management.Automation.PSObject $IPResult | Add-Member -MemberType NoteProperty -Name IPAddress -Value $Address $ConnTestPing = Test-Connection -Count 1 -computername $Address -Quiet $ConnTestPort = Test-NetConnection -ComputerName $Address -Port 88 -InformationLevel Quiet if ($ConnTestPing -eq $true) { $IPResult | Add-Member -MemberType NoteProperty -Name PingTest -Value $true } else { $IPResult | Add-Member -MemberType NoteProperty -Name PingTest -Value $false } if ($ConnTestPort -eq $true) { $IPResult | Add-Member -MemberType NoteProperty -Name PortTest -Value $true } else { $IPResult | Add-Member -MemberType NoteProperty -Name PortTest -Value $false } $TempResult += $IPResult } $Result |Add-Member -MemberType NoteProperty -Name TestResults -Value $TempResult return $Result } function Get-DomainControllerUpTime($DomainController, $Credential) { try { Write-Host "Getting DC WMI Object" $W32OS = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $DomainController -credential $Credential | select * Write-Host "Converting to proper format" $timespan = [System.Management.ManagementDateTimeConverter]::ToDateTime($W32OS.LocalDateTime).ToUniversalTime() - [System.Management.ManagementDateTimeConverter]::ToDateTime($W32OS.LastBootUpTime).ToUniversalTime() [double]$uptime = "{0:N2}" -f $timespan.TotalHours } catch [exception] { $uptime = 'WMI Failure' } return $uptime } function get-userADlastlogon ($UserName, $Credential, $Domain, $DCs) { Write-Host "Getting lastlogon for user $($UserName)" $LastLogon = 0 foreach ($DC in $DCs) { Write-Host "Processing DC:$($DC.hostname)" #$Result = Verify-DomainControllerIP -DomainController $DC.hostname #foreach ($R in $Result.testresults) #{ #if ($R.porttest -eq $true) #{ #$IP = $R.IPAddress #Write-Host "Using IP:$($IP.ipaddress)" $CurrentUser = Get-ADUser -identity $UserName -Server $DC.hostname -Credential $Credential | Get-ADObject -Server $DC.hostname -properties Lastlogon -Credential $Credential if ($CurrentUser.lastlogon -gt $LastLogon) { $LastLogon = $CurrentUser.lastlogon } #} #} } $LastLogonDT = [DateTime]::FromFileTime($LastLogon) return $LastLogonDT } function Export-LastLogonReport ($Domain, $Credential, [array]$Fields, $OutputFile) { $DCs = get-onlinedomaincontrollers -Domain $Domain -Credential $Credential $IP = Resolve-DnsName -Name $DCs[0].hostname $Users = Get-ADUser -Credential $Credential -Server $IP.ipaddress -Properties $Fields -Filter * foreach ($User in $Users) { Write-Host "Processing user: $($User.samaccountname)" $LL = get-userADlastlogon -UserName $User.samaccountname -Credential $Credential -Domain $Domain -DCs $DCs $Users | ?{$_.samaccountname -eq $User.samaccountname}|Add-Member -MemberType NoteProperty -Name LastlogonCorrected -Value $LL -force } $Users | Export-Csv -Path $OutputFile -NoTypeInformation } function get-onlinedomaincontrollers ($Domain, $Credential) { Write-Host "Getting Online DCs for Domain: $($Domain)" $DCs = Get-AllDomainControllers -DomainName $Domain -Credential $Credential $returnDC = @() foreach ($DC in $Dcs) { Write-Host "Checking Domain Controller $($DC.hostname)" $alive = $false $result = Verify-DomainControllerIP -DomainController $DC.hostname foreach ($r in $result.testresults) { if ($R.porttest -eq $true) { $alive = $true } } if ($alive -eq $true) { Write-Host "DC is alive and responding." $returnDC += $DC } } return $returnDC } Function Get-ADUserLockouts { [CmdletBinding( DefaultParameterSetName = 'All' )] param ( [Parameter( ValueFromPipeline = $true, ParameterSetName = 'ByUser' )] [Microsoft.ActiveDirectory.Management.ADUser]$Identity , [datetime]$StartTime , [datetime]$EndTime ) Begin { $filterHt = @{ LogName = 'Security' ID = 4740 } if ($PSBoundParameters.ContainsKey('StartTime')) { $filterHt['StartTime'] = $StartTime } if ($PSBoundParameters.ContainsKey('EndTime')) { $filterHt['EndTime'] = $EndTime } $PDCEmulator = (Get-ADDomain).PDCEmulator # Query the event log just once instead of for each user if using the pipeline $events = Get-WinEvent -ComputerName $PDCEmulator -FilterHashtable $filterHt } Process { if ($PSCmdlet.ParameterSetName -eq 'ByUser') { $user = Get-ADUser $Identity # Filter the events $output = $events | Where-Object { $_.Properties[0].Value -eq $user.SamAccountName } } else { $output = $events } foreach ($event in $output) { [pscustomobject]@{ UserName = $event.Properties[0].Value CallerComputer = $event.Properties[1].Value TimeStamp = $event.TimeCreated } } } End { } } |