PSPowerAdminTasks.psm1
#Region '.\Classes\01CLASS_COMPUTER.ps1' 0 class COMPUTER { #region <Properties> [System.String]$Name [System.DateTime]$CheckTime [System.String]$Status [System.String]$SamAccountName [System.String]$CN [System.String]$Operatingsystem [System.String]$Description [System.String]$IPv4Address [System.String]$Created [System.String]$LastLogontimestamp [System.String]$CanonicalName [System.String]$MemberOF [System.String]$HotFixDescription [System.String]$HotfixID [System.String]$HotFixInstalledBy [System.String]$HotFixInstalledOn [System.String]$LastBootUptime [System.String]$RebootNeeded HIDDEN [System.Management.Automation.PSCredential]$Credential #endregion <Properties> #region <Constructor> COMPUTER() { } COMPUTER([string]$ComputerName) { $This.CheckTime = Get-Date $this.Name = $ComputerName $this.TestIfComputerIsOnline($ComputerName) } COMPUTER([string]$ComputerName, [System.Management.Automation.PSCredential]$Credential) { $This.Credential = $Credential $this.Name = $ComputerName $this.TestIfComputerIsOnline($ComputerName) } #endregion <Constructor> #region <Methods> [void] GetALlInformation () { if ($this.Status -eq "Ping OK") { $This.CheckTime = Get-Date $this.TestIfComputerExistInAd() $this.GetComputerLastHotFix() $this.GetComputerLastBootUptime() $this.TestIfRebootNeeded() } } [void] TestIfComputerIsOnline([string]$ComputerName) { try { if (Test-Connection -ComputerName $ComputerName -Count 1 -ErrorAction Stop) { $this.Status = "Ping OK" } else { $this.Status = "Ping KO" } } catch { $this.Status = "Host Unknown" } } [Boolean] TestIfComputerExistInAd () { $Parameter = @{ Properties = 'Name', 'SamAccountName', 'CN', 'Operatingsystem', 'Description', 'IPv4Address', 'Created', 'LastLogontimestamp', 'CanonicalName', 'MemberOF' Filter = { Name -eq $This.Name } ErrorAction = "SilentlyContinue" } if ($null -ne $this.Credential) { $Parameter.Add('Credential', $this.Credential) } $Computer = Get-ADComputer @Parameter if ($Computer) { try { $this.SamAccountName = $Computer.SamAccountName $this.CN = $Computer.CN $this.Operatingsystem = $Computer.Operatingsystem $this.Description = $Computer.Description $this.IPv4Address = $Computer.IPv4Address $this.Created = $Computer.Created $this.LastLogontimestamp = [DateTime]::FromFileTime($Computer.LastLogontimestamp) $this.CanonicalName = $Computer.CanonicalName if ($Computer.MemberOF.Count -gt 0) { $this.MemberOF = ($Computer.MemberOf -like "*WSUS*").split("=")[1].split(",")[0] } else { $This.MemberOF = "No WSUS Group" } } catch [System.Management.Automation.MethodException] { Write-Output ('[{0:O}] ErrorID: {1}' -f (get-date),$_.Exception.Message) Write-Output ('[{0:O}] Exception: {1}' -f (get-date),$_.FullyQualifiedErrorId) Write-Output ('[{0:O}] Category: {1}' -f (get-date),(($_.Exception.GetType() | Select-Object -ExpandProperty UnderlyingSystemType).FullName)) } catch { Write-Output ('[{0:O}] ErrorID: {1}' -f (get-date),$_.Exception.Message) Write-Output ('[{0:O}] Exception: {1}' -f (get-date),$_.FullyQualifiedErrorId) Write-Output ('[{0:O}] Category: {1}' -f (get-date),(($_.Exception.GetType() | Select-Object -ExpandProperty UnderlyingSystemType).FullName)) } return $true } else { $this.SamAccountName = "Unknown" $this.CN = "Unknown" $this.Operatingsystem = "Unknown" $this.Description = "Unknown" $this.IPv4Address = "Unknown" $this.Created = "Unknown" $this.LastLogontimestamp = "Unknown" $this.CanonicalName = "Unknown" $this.MemberOF = "Unknown" return $false } } [Void] GetComputerLastHotFix () { try { $HotfixParameter = @{ ComputerName = $this.CN ErrorAction = "Stop" } if ($null -ne $this.Credential) { $HotfixParameter['Credential'] = $this.Credential } $hotfix = Get-HotFix @HotfixParameter | Sort-Object -Descending -Property InstalledOn | Select-Object -First 1 | Select-Object Description, HotfixID, InstalledBy, InstalledOn $this.HotfixID = $hotfix.HotfixID $this.HotFixDescription = $hotfix.Description $this.HotFixInstalledBy = $hotfix.InstalledBy $this.HotFixInstalledOn = $hotfix.InstalledOn } catch [System.UnauthorizedAccessException] { $this.HotfixID = "UnauthorizedAccessException" $this.HotFixDescription = "UnauthorizedAccessException" $this.HotFixInstalledBy = "UnauthorizedAccessException" $this.HotFixInstalledOn = "UnauthorizedAccessException" } catch { $this.HotfixID = "Unknown" $this.HotFixDescription = "Unknown" $this.HotFixInstalledBy = "Unknown" $this.HotFixInstalledOn = "Unknown" } } [Void] GetComputerLastBootUptime () { try { $Parameter = @{ ComputerName = $this.CN ErrorAction = "Stop" } if ($null -ne $this.Credential) { $Parameter['Credential'] = $this.Credential } $this.LastBootUptime = Invoke-Command @Parameter -ScriptBlock {(Get-CimInstance -ClassName Win32_OperatingSystem | Select-Object -ExpandProperty LastBootUpTime)} } catch { Write-Output ('[{0:O}] ErrorID: {1}' -f (get-date),$_.Exception.Message) Write-Output ('[{0:O}] Exception: {1}' -f (get-date),$_.FullyQualifiedErrorId) Write-Output ('[{0:O}] Category: {1}' -f (get-date),(($_.Exception.GetType() | Select-Object -ExpandProperty UnderlyingSystemType).FullName)) $this.LastBootUptime = "Unknown" } } [void] TestIfRebootNeeded () { if ($this.Status -eq "Ping OK") { try { $CmdParameter = @{ ComputerName = $this.CN ErrorAction = "Stop" Authentication = "Kerberos" } if ($null -ne $this.Credential) { $CmdParameter['Credential'] = $this.Credential } $this.RebootNeeded = Invoke-Command @CmdParameter -ScriptBlock { if ((Get-ChildItem "HKLM:\Software\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending" -ErrorAction SilentlyContinue) -or (Get-Item "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired" -ErrorAction SilentlyContinue) ) { write-output "YES" } else { Write-output "NO" } } } catch { $This.RebootNeeded = "Unknown" } } } #endregion <Methods> } #EndRegion '.\Classes\01CLASS_COMPUTER.ps1' 230 #Region '.\Private\Process-Start.ps1' 0 function Process-Start ([string]$FilePath, [string]$Arguments) { Try { $Info = New-Object System.Diagnostics.ProcessStartInfo $Process = New-Object System.Diagnostics.Process $Info.FileName = $FilePath $Info.RedirectStandardError = $true $Info.RedirectStandardOutput = $true $Info.UseShellExecute = $false $Info.Arguments = $Arguments $Info.WorkingDirectory = "C:\Windows\System32" $Process.StartInfo = $Info $Process.Start() | Out-Null [string]$stdOut = $Process.StandardOutput.ReadToEnd() [string]$stdErr = $Process.StandardError.ReadToEnd() $Process.WaitForExit(10000) # Wait maximum of 10 seconds If ($process.ExitCode -eq 0) { Return ($stdOut.Split("`n")) } # Standard Output Else { If ($stdErr.Length -gt 0) { Return ($stdErr.Split("`n")) } # Standard Error (if it exists) Else { Return ($stdOut.Split("`n")) } # Standard Output (if there are no errors) } } Catch { Return "ERROR: $($_.Exception.Message)" } } #EndRegion '.\Private\Process-Start.ps1' 29 #Region '.\Private\Write-Log.ps1' 0 function Write-Log { <# .SYNOPSIS Write a log file .DESCRIPTION Write all operation passed as parameter to a log file .PARAMETER LogPath Path to logfile. By default, the logfile is created in the temp folder of the current user .PARAMETER Message Message to write in the log file .PARAMETER Severity Severity of the message. By default, the severity is set to Information .PARAMETER Console Show the message in the console .PARAMETER Force Forece the creation of the log file .EXAMPLE Write-log -Message 'Starting Set-ChangePasswordAtNextLogon' -Severity Information -Console .NOTES General notes #> [CmdletBinding()] param ( [Parameter()] [ValidateNotNullOrEmpty()] [System.String]$LogPath = "$env:Temp\LogFile.csv", [Parameter()] [ValidateNotNullOrEmpty()] [string]$Message, [Parameter()] [ValidateNotNullOrEmpty()] [ValidateSet('Information', 'Warning', 'Error')] [string]$Severity = 'Information', [Parameter()] [switch]$Console, [Parameter()] [switch]$Force ) $info = [pscustomobject]@{ Severity = "[$($Severity)]" Time = ((Get-Date).toString("yyyy/MM/dd HH:mm:ss")) Message = $Message } if ($Console) { Write-Output "$($info.Severity) $($info.Time) $($info.Message)" } if ($Force) { $info | Export-Csv -Path $LogPath -NoTypeInformation -Force } else { $info | Export-Csv -Path $LogPath -NoTypeInformation -Append } } #EndRegion '.\Private\Write-Log.ps1' 75 #Region '.\Public\Disable-CompromisedUser.ps1' 0 function Disable-CompromisedUser { <# .SYNOPSIS Disable compromised user .DESCRIPTION In case of compromission from some users, you can rapidly disable this users. You can pass to parameter : - a nominative list of user - a file with a nominative list of users (one user by line) - an OU to disable all users Check example for more details (get-help Disable-CompromisedUser -Examples) A log file is create in your temp directory ($env:temp) .PARAMETER Identity One or more user(s) to disable .PARAMETER FileName File with a list of users to disable. txt with one name by line .PARAMETER OU One or more OU(s) in which we want to disable all users .PARAMETER Check Only check if the users passed in parameter, whatever the way (Identity, Filename or OU), are disable .PARAMETER Credential Specifies the user account credentials to use when performing this task .PARAMETER Log Log information in a file (in $env:Temp ) .PARAMETER Console Show information in console (need Log parameter) .EXAMPLE Disable-CompromisedUser -Identity "User1" Disable the user account : User1 .EXAMPLE Disable-CompromisedUser -Identity "User1" -Log Disable the user account : User1 and log information in file in $env:temp .EXAMPLE Disable-CompromisedUser -Identity "User1" -Log -Console Disable the user account : User1, log information in file in $env:temp and log to console the same information .EXAMPLE Disable-CompromisedUser -Identity "User1" -Check Check if user account User1 is disable .EXAMPLE Disable-CompromisedUser -Identity "User1","User2","User3" Disable users account : User1, User2 and User3 .EXAMPLE Disable-CompromisedUser -Identity "User1","User2","User3" -Check Check if users account User1, User2 and User3 are disable .EXAMPLE Disable-CompromisedUser -FileName "c:\temp\CompromisedUser.txt" File template CompromisedUser.txt : User1 User2 User3 Disable users account : User1, User2 and User3 .EXAMPLE Disable-CompromisedUser -FileName "c:\temp\CompromisedUser.txt" -Check File template CompromisedUser.txt : User1 User2 User3 Check if users account User1, User2 and User3 are disable .EXAMPLE Disable-CompromisedUser -OU "OU=OU1,DC=contoso,DC=com" Disable all users present in OU1 .EXAMPLE Disable-CompromisedUser -OU "OU=OU1,DC=contoso,DC=com" -Check Check if all users present in OU1 are disable .EXAMPLE Disable-CompromisedUser -OU "OU=OU1,DC=contoso,DC=com","OU=OU2,DC=contoso,DC=com" Disable all users present in OU1 and OU2 .EXAMPLE Disable-CompromisedUser -OU "OU=OU1,DC=contoso,DC=com","OU=OU2,DC=contoso,DC=com" -check Check if all users present in OU1 and OU2 are disable .NOTES General notes #> [CmdletBinding(DefaultParameterSetName = "ByUser")] param ( [Parameter( ParameterSetName = "ByUser", HelpMessage = 'One or more user(s) to disable' )] [System.String[]]$Identity, [Parameter( ParameterSetName = "ByFileName", HelpMessage = 'File with a list of users to disable. txt with one name by line' )] [System.String]$FileName, [Parameter( ParameterSetName = "ByOu", HelpMessage = 'One or more OU(s) in which we want to disable all users' )] [System.String[]]$OU, [Parameter( HelpMessage = 'Only check if the users passed in parameter, whatever the way (Identity, Filename or OU), are disable' )] [Switch]$Check, [Parameter( HelpMessage = "Specifies the user account credentials to use when performing this task." )] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty, [Parameter( HelpMessage = 'Log information in a file' )] [switch]$log, [Parameter( HelpMessage = 'Show information in console' )] [switch]$Console ) begin { if ($log) { $LogPath = $env:Temp + '\Disable-CompromisedUser.csv' Write-Log -LogPath $LogPath -Message 'Starting Disable-CompromisedUser' -Severity Information -Console:$Console } $Users = @() switch ($PSCmdlet.ParameterSetName) { ByUser { if ($log) { write-log -LogPath $LogPath -Message "Retrieve AD User Account by user list" -Severity Information -Console:$Console} foreach ($User in $Identity) { try { $Users += Get-ADUser -Identity $User -Properties SamAccountName,DisplayName,Enabled -ErrorAction Continue | Select-Object SamAccountName,DisplayName,Enabled if ($log) { write-log -LogPath $LogPath -Message "User $($User) found" -Severity Information -Console:$Console} } catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] { if ($log) { write-log -LogPath $LogPath -Message "User $($User) not found" -Severity Error -Console:$Console} } } } ByFileName { if ($log) { write-log -LogPath $LogPath -Message "Retrieve AD User Account by file list" -Severity Information -Console:$Console} foreach ($User in (Get-Content -Path $FileName)) { try { $Users += Get-ADUser -Identity $User -Properties SamAccountName,DisplayName,Enabled -ErrorAction Continue | Select-Object SamAccountName,DisplayName,Enabled if ($log) { write-log -LogPath $LogPath -Message "User $($User) found" -Severity Information -Console:$Console} } catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] { if ($log) { write-log -LogPath $LogPath -Message "User $($User) not found" -Severity Error -Console:$Console} } } } ByOu { if ($log) { write-log -LogPath $LogPath -Message "Retrieve AD User Account by OU list" -Severity Information -Console:$Console} foreach ($Organ in $OU) { if ($log) { write-log -LogPath $LogPath -Message "Retrieve AD User Account in $($Organ)" -Severity Information -Console:$Console} $Users += Get-ADUser -Filter * -SearchBase $Organ -Properties SamAccountName,DisplayName,Enabled | Select-Object SamAccountName,DisplayName,Enabled } } } } process { $Arguments = @{} if ($PSBoundParameters.ContainsKey('Credential')) { $Arguments['Credential'] = $Credential } foreach ($user in $Users) { if ($Check) { if ($log) { write-log -LogPath $LogPath -Message "Check state for user $( $User.SamAccountName)" -Severity Information -Console:$Console} if ($user.Enabled -eq "True") { if ($log) { write-log -LogPath $LogPath -Message "user $($User.SamAccountName) is enabled" -Severity Information -Console:$Console} } else { if ($log) { write-log -LogPath $LogPath -Message "user $($User.SamAccountName) is disabled" -Severity Information -Console:$Console} } } else { $Arguments['Identity'] = $Users.SamAccountName Disable-ADAccount @Arguments -Confirm:$false if ($log) { write-log -LogPath $LogPath -Message "Disabeling user $($User.SamAccountName)" -Severity Information -Console:$Console} } } } end { if ($log) { write-log -LogPath $LogPath -Message "Ending Disable-CompromisedUser" -Severity Information -Console:$Console } } } #EndRegion '.\Public\Disable-CompromisedUser.ps1' 247 #Region '.\Public\Find-InExcel.ps1' 0 function Find-InExcel { <# .SYNOPSIS Find information in a excel file .DESCRIPTION This function return any informations from any Excel File. This function is based on the headers present in Excel file .PARAMETER FilePath Full path from de Excel file .PARAMETER WorkSheetName Name of the worksheet- where i was looking for the information. "Sheet1" by default .PARAMETER HeaderRow Number of the header row. "1" by defaults .PARAMETER SearchRow Column name used to filter the search .PARAMETER DataRow Column name return after the search. Can be on or more column .PARAMETER SearchValue The value tos search for in the column SearchRow .EXAMPLE Find-InExcel -FilePath "C:\PathToMyFile\MyFile.xlsx" -WorksheetName "Worksheet1" -HeaderRow "1" -SearchRow "Column1" -SearchValue "MyValue" -DataRow "Column3" .EXAMPLE Find-InExcel -FilePath "C:\PathToMyFile\MyFile.xlsx" -WorksheetName "Worksheet1" -HeaderRow "1" -SearchRow "Column1" -SearchValue "MyValue" -DataRow "Column3","Column1","Column2" .NOTES General notes #> [CmdletBinding()] param ( [Parameter()] [ValidateScript({ if (-Not ($_ | Test-Path) ) { throw "File or folder does not exist" } if (-Not ($_ | Test-Path -PathType Leaf) ) { throw "The Path argument must be a file. Folder paths are not allowed." } if ($_ -notmatch "(\.xlsx)") { throw "The file specified in the path argument must be either of type xlsx" } return $true })] [System.IO.FileInfo]$FilePath, [Parameter()] [ArgumentCompleter( { param ( $Command, $Parameter, $WordToComplete, $CommandAst, $FakeBoundParams ) Get-ExcelSheetInfo -Path $Fakeboundparams.FilePath | Where-Object { $_.Name -like "*$WordToComplete*" } | Select-Object -ExpandProperty Name })] [System.String]$WorkSheetName = "Sheet1", [Parameter()] [System.String]$HeaderRow = "1", [Parameter()] [ArgumentCompleter( { param ( $Command, $Parameter, $WordToComplete, $CommandAst, $FakeBoundParams ) Import-Excel -Path $Fakeboundparams.FilePath -WorksheetName $Fakeboundparams.WorkSheetName -HeaderRow $Fakeboundparams.HeaderRow | Get-Member -MemberType NoteProperty | Where-Object { $_.Name -like "*$WordToComplete*" } | Select-Object -ExpandProperty Name })] [System.String]$SearchRow, [Parameter()] [ArgumentCompleter( { param ( $Command, $Parameter, $WordToComplete, $CommandAst, $FakeBoundParams ) Import-Excel -Path $Fakeboundparams.FilePath -WorksheetName $Fakeboundparams.WorkSheetName -HeaderRow $Fakeboundparams.HeaderRow | Select-Object -exp $Fakeboundparams.SearchRow })] [System.string[]]$SearchValue = '*', [Parameter()] [ArgumentCompleter( { param ( $Command, $Parameter, $WordToComplete, $CommandAst, $FakeBoundParams ) Import-Excel -Path $Fakeboundparams.FilePath -WorksheetName $Fakeboundparams.WorkSheetName -HeaderRow $Fakeboundparams.HeaderRow | Get-Member -MemberType NoteProperty | Where-Object { $_.Name -like "*$WordToComplete*" } | Select-Object -ExpandProperty Name })] [System.String[]]$DataRow ) begin { Import-Module ImportExcel -Verbose:$false Write-Verbose ('[{0:O}] Importing data from {1}' -f (get-date), $FilePath) $Data = Import-Excel -Path $FilePath -WorksheetName $WorkSheetName -HeaderRow $HeaderRow Write-Verbose ('[{0:O}] Headers validation' -f (get-date)) $FileHeaders = $data | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty Name foreach ($header in ($DataRow + $SearchRow)) { if ($header -notin $FileHeaders) { throw "Header $($Header) not found" } else { Write-Verbose ('[{0:O}] Header "{1}" validate' -f (get-date), $Header) } } } process { $Result = @() if ($SearchValue -eq "*") { $Result = $data | Select-Object -Property $DataRow } else { foreach ($Value in $SearchValue) { Write-Verbose ('[{0:O}] Searching {1} in column {2}' -f (get-date), $Value, $SearchRow) $Result += $data | Where-Object { $_.$SearchRow -eq $Value } | Select-Object -Property $DataRow } } } end { $Result } } #EndRegion '.\Public\Find-InExcel.ps1' 153 #Region '.\Public\Find-InSupDB.ps1' 0 function Find-InSupDB { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$URL, # Parameter help description [Parameter()] [System.String]$ComputerName ) begin { } process { # Récupérer le contenu HTML du site web $Html = Invoke-WebRequest -Uri $Url # récupérer les entêtes de colonnes et le contenu du tableau et les convertir en objet $Tableau = $Html.ParsedHtml.getElementsByTagName("tr") | Select-Object -Skip 1 | ForEach-Object { [PSCustomObject]@{ Server = $_.getElementsByTagName("td")[0].innerText Actif = $_.getElementsByTagName("td")[1].innerText Ip_address = $_.getElementsByTagName("td")[2].innerText Plateform = $_.getElementsByTagName("td")[3].innerText Port = $_.getElementsByTagName("td")[5].innerText Type = $_.getElementsByTagName("td")[7].innerText RDBMS = $_.getElementsByTagName("td")[10].innerText version = $_.getElementsByTagName("td")[11].innerText } } } end { $Tableau | Where-Object {$_.Server -eq $ComputerName} } } #EndRegion '.\Public\Find-InSupDB.ps1' 42 #Region '.\Public\Find-UserLockoutsInformation.ps1' 0 Function Find-UserLockoutsInformation { <# .SYNOPSIS Find information about locked user account .DESCRIPTION This fonction search for locked user on PDC Emulator and return the lock source return : User : User1 DomainController : PDCEmulator EventId : 4740 LockoutTimeStamp : 8/3/2023 6:18:12 AM Message : A user account was locked out. LockoutSource : SourceComputer To find the reason use : Get-UserLockoutReason -Computer SourceComputer -Identity User1 .PARAMETER Identity User to check (by default all) .PARAMETER DC Domain controller on which you want to look up information (by default PDC Emulator) .PARAMETER Credential Administrator credential to connect to the DC .EXAMPLE Find-UserLockoutsInformation -Credential (Get-Credential MyAdminAccount) Search information for all locked users in PDC Emulator .EXAMPLE Find-UserLockoutsInformation -Identity User1 -Credential (Get-Credential MyAdminAccount) Search information for user User1 in PDC Emulator .EXAMPLE Find-UserLockoutsInformation -Identity User1 -DC MyDC1 -Credential (Get-Credential MyAdminAccount) Search information for user User1 in specific domain controler MyDC1 .NOTES General notes #> [CmdletBinding( DefaultParameterSetName = 'All' )] param ( [Parameter( ValueFromPipeline = $true, ParameterSetName = 'ByUser' )] [System.String]$Identity, [System.String]$DC = (Get-ADDomain).PDCEmulator, # Specifies the user account credentials to use when performing this task. [Parameter()] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty ) Begin { Write-Verbose ('[{0:O}] Searching EventID : 4740 on Server : {1} ' -f (get-date), $DC) $WinEventArguments = @{ ComputerName = $DC FilterHashtable = @{LogName = 'Security'; Id = 4740 } } if ($PSBoundParameters.ContainsKey('Credential')) { $WinEventArguments['Credential'] = $Credential } try { $LockedOutEvents = Get-WinEvent @WinEventArguments -ErrorAction Stop | Sort-Object -Property TimeCreated -Descending } catch { if ($Error[-1].Exception.Message -like "*elevated user rights*") { throw ('[{0:O}] You need an admin account. Please provide with the -Credential parameter' -f (get-date)) } } if ($LockedOutEvents) { Write-Verbose ('[{0:O}] {1} event found' -f (get-date), $LockedOutEvents.Count) } else { throw ('[{0:O}] No event found' -f (get-date)) } } Process { switch ($PSCmdlet.ParameterSetName) { ByUser { Write-Verbose ('[{0:O}] Searching information for user : {1}' -f (get-date), $Identity) $UserInfo = Get-ADUser -Identity $Identity Foreach ($Event in $LockedOutEvents) { If ($Event | Where-Object { $_.Properties[2].value -match $UserInfo.SID.Value }) { $Event | Select-Object -Property @( @{Label = 'User'; Expression = { $_.Properties[0].Value } } @{Label = 'DomainController'; Expression = { $_.MachineName } } @{Label = 'EventId'; Expression = { $_.Id } } @{Label = 'LockoutTimeStamp'; Expression = { $_.TimeCreated } } @{Label = 'Message'; Expression = { $_.Message -split "`r" | Select-Object -First 1 } } @{Label = 'LockoutSource'; Expression = { $_.Properties[1].Value } } ) } } } All { Write-Verbose ('[{0:O}] Searching information for all user(s) ' -f (get-date)) Foreach ($Event in $LockedOutEvents) { $Event | Select-Object -Property @( @{Label = 'User'; Expression = { $_.Properties[0].Value } } @{Label = 'DomainController'; Expression = { $_.MachineName } } @{Label = 'EventId'; Expression = { $_.Id } } @{Label = 'LockoutTimeStamp'; Expression = { $_.TimeCreated } } @{Label = 'Message'; Expression = { $_.Message -split "`r" | Select-Object -First 1 } } @{Label = 'LockoutSource'; Expression = { $_.Properties[1].Value } } ) } } } } End { } } #EndRegion '.\Public\Find-UserLockoutsInformation.ps1' 134 #Region '.\Public\Get-ADForestRootDomain.ps1' 0 Function Get-ADForestRootDomain { <# .SYNOPSIS Récupère l’objet AD Domain de la racine pour la forêt courante. .DESCRIPTION Remonte l’arborescence de domaine jusqu’à la racine et renvoi l’objet .PARAMETERS domain Le domaine de départ, par défaut le courant .OUTPUTS l’objet AD Domaine racine de la forêt .EXAMPLE PS C:> Get-ADForestRootDomain -domain unico.rn .AUTHORS TiTi .LASTUPDATE 2015-06-08 #> [CmdletBinding()] Param ( $domain = (Get-ADDomain) ) $current = Get-ADDomain $domain #on remonte dans l’arborescence, c’est-à -dire : tant que le domaine parent n’est pas vide. while($current.ParentDomain -ne $null){ $current = Get-ADDomain $current.ParentDomain } Return $current } #EndRegion '.\Public\Get-ADForestRootDomain.ps1' 29 #Region '.\Public\Get-ADGroupSubGroupMember.ps1' 0 Function Get-ADGroupSubGroupMember { <# .SYNOPSIS Fournie la liste des groupes imbriqués pour un groupe donné .DESCRIPTION Appel récursif sur l’attribut member du groupe en entrée pour obtenir la liste des membres de types « group » du groupe en entrée, tout en gérant les boucles éventuelles dans les groupes enfant. .PARAMETERS Group Le groupe à traiter .PARAMETERS ProcessedGroup Les groupes déjà traités pour éviter les boucles imbriquée, et appels infinis. .OUTPUTS La liste des sous-groupes du groupe en entrée (incluant le groupe initial). .EXAMPLE PS C:> Get-ADGroupSubGroupMember 'test3' .AUTHORS TiTi .LASTUPDATE 2015-06-11 #> [CmdletBinding()] Param( $Group, $ProcessedGroup = @() ) #groupe traité $ProcessedGroup += Get-ADGroup $Group #On récupère les sous-groupes $SubGroupMember = @(Get-ADGroupMember $Group | Where-Object {$_.objectClass -eq 'group'}) if($SubGroupMember -eq $null){ #si pas de sous-groupe, on retourne les groupes traités return $ProcessedGroup }else{ #Pour chaque sous-groupe(s), on rappelle la fonction foreach($SubGroup in $SubGroupMember){ if($SubGroup.SID -notin $ProcessedGroup.SID){ $ProcessedGroup = @(Get-ADGroupSubGroupMember -Group $SubGroup -ProcessedGroup $ProcessedGroup) } } # Et on retourne les groupes traités return $ProcessedGroup } } #EndRegion '.\Public\Get-ADGroupSubGroupMember.ps1' 43 #Region '.\Public\Get-BitLockerInformation.ps1' 0 function Get-BitLockerInformation { <# .SYNOPSIS Retreive BitLocker information from Active Directory .DESCRIPTION Retreive BitLocker information for computer pass as parameter from Active Directory .PARAMETER Computer Computer name .PARAMETER Credential Credential with permission to read bitlocker information in Active Directory .EXAMPLE Get-BitlockerInformation -Computer "ComputerName" -Credential $MyCredential Find bitlocker information for computer "ComputerName" with credential .NOTES General notes #> [CmdletBinding()] param( [Parameter(ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)] [System.String[]]$Computer, [Parameter()] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty ) begin { $Result = @() $Argument = @{ Filter = { ObjectClass -eq 'msFVE-RecoveryInformation' } Properties = 'msFVE-RecoveryPassword' } If ($PSBoundParameters.ContainsKey("Credential")) { $Argument.Add("Credential", $Credential) } } process { foreach ($Comp in $Computer) { Write-Verbose "Check computer : $($Comp)" $objComputer = Get-ADComputer -Identity $Comp $BitLockerObject = Get-ADObject @Argument -SearchBase $objComputer.DistinguishedName if ($BitLockerObject) { $Bitlock = $BitLockerObject | Sort-Object Name | Select-Object -last 1 $object = [PSCustomObject]@{ "Computer" = $Comp "Password ID" = $Bitlock.Name.split("{")[1].split("}")[0] "Date" = $Bitlock.Name.split("{")[0] "Recovery Key" = $Bitlock.'msFVE-RecoveryPassword' } $Result += $object } else { $object = [PSCustomObject]@{ "Computer" = $Comp "Password ID" = "null" "Date" = "null" "Recovery Key" = "null" } $Result += $object } } } end { return $Result } } #EndRegion '.\Public\Get-BitLockerInformation.ps1' 80 #Region '.\Public\Get-DirectorySize.ps1' 0 function Get-DirectorySize { param ( [Parameter(ValueFromPipeline)] [Alias('PSPath')] [string] $LiteralPath = '.', [switch] $Recurse, [switch] $ExcludeSelf, [int] $Depth = -1, [int] $__ThisDepth = 0 # internal use only ) process { # Resolve to a full filesystem path, if necessary $fullName = if ($__ThisDepth) { $LiteralPath } else { Convert-Path -ErrorAction Stop -LiteralPath $LiteralPath } if ($ExcludeSelf) { # Exclude the input dir. itself; implies -Recurse $Recurse = $True $ExcludeSelf = $False } else { # Process this dir. $NbOfFiles = (Get-ChildItem -Force -File -LiteralPath $fullName).Count # Calculate this dir's total logical size. # Note: [System.IO.DirectoryInfo].EnumerateFiles() would be faster, # but cannot handle inaccessible directories. $size = [Linq.Enumerable]::Sum( [long[]] (Get-ChildItem -Force -Recurse -File -LiteralPath $fullName).ForEach('Length') ) # Create a friendly representation of the size. $decimalPlaces = 2 $padWidth = 8 $scaledSize = switch ([double] $size) { { $_ -ge 1tb } { $_ / 1tb; $suffix = 'tb'; break } { $_ -ge 1gb } { $_ / 1gb; $suffix = 'gb'; break } { $_ -ge 1mb } { $_ / 1mb; $suffix = 'mb'; break } { $_ -ge 1kb } { $_ / 1kb; $suffix = 'kb'; break } default { $_; $suffix = 'b'; $decimalPlaces = 0; break } } # Construct and output an object representing the dir. at hand. [pscustomobject] @{ FullName = $fullName FriendlySize = ("{0:N${decimalPlaces}}${suffix}" -f $scaledSize).PadLeft($padWidth, ' ') Size = $size Files = $NbOfFiles } } # Recurse, if requested. if ($Recurse -or $Depth -ge 1) { if ($Depth -lt 0 -or (++$__ThisDepth) -le $Depth) { # Note: This top-down recursion is inefficient, because any given directory's # subtree is processed in full. Get-ChildItem -Force -Directory -LiteralPath $fullName | ForEach-Object { Get-DirectorySize -LiteralPath $_.FullName -Recurse -Depth $Depth -__ThisDepth $__ThisDepth } } } } } #EndRegion '.\Public\Get-DirectorySize.ps1' 97 #Region '.\Public\Get-LastUpdateInformation.ps1' 0 function Get-LastUpdateInformation { <# .SYNOPSIS Retrieve update information .DESCRIPTION Retrieve update information for a server the data is : Name CheckTime Status SamAccountName CN Operatingsystem Description IPv4Address Created LastLogontimestamp CanonicalName MemberOF HotFixDescription HotfixID HotFixInstalledBy HotFixInstalledOn LastBootUptime RebootNeeded .PARAMETER ComputerName One or more computer(s) to check .PARAMETER Credential Administrator credential to connect to the computer .EXAMPLE Get-LastUpdateInformation -ComputerName MyServer -Credential (Get-Credential MyAdminAccount) -Verbose Search last update information foe server MyServer using credential to connect .NOTES General notes #> [CmdletBinding()] [OutputType([System.Object[]])] param ( [Parameter(Mandatory = $true)] [System.String[]]$ComputerName, # Specifies the user account credentials to use when performing this task. [Parameter()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()]$Credential ) begin { $result = @() } process { if ($null -ne $Credential) { foreach ($computer in $ComputerName) { Write-Verbose ('[{0:O}] Computer {1}' -f (get-date),$computer) $Infos = [COMPUTER]::new($computer, $Credential) $Infos.GetALlInformation() $result += $Infos } } else { foreach ($computer in $ComputerName) { Write-Verbose ('[{0:O}] Computer {1}' -f (get-date),$computer) $Infos = [COMPUTER]::new($computer) $Infos.GetALlInformation() $result += $Infos } } } end { return $result } } #EndRegion '.\Public\Get-LastUpdateInformation.ps1' 87 #Region '.\Public\Get-UserLockoutReason.ps1' 0 function Get-UserLockoutReason { <# .SYNOPSIS Search user lockout reason .DESCRIPTION You can search the reason of locked user on a specific computer To find the source you can use : Find-UserLockoutsInformation -Identity User1 -DC MyDC1 -Credential (Get-Credential MyAdminAccount) .PARAMETER Computer User lockout source computer .PARAMETER Identity Name of the user for whom we are looking for the source of the lock .PARAMETER Credential Administrator credential to connect to the computer .EXAMPLE Get-UserLockoutReason -Computer ComputerSource -Identity User1 -Credential (Get-Credential MyAdminAccount) .NOTES General notes #> [CmdletBinding( DefaultParameterSetName = 'All' )] [OutputType([System.Object[]])] param ( [System.String]$Computer, [Parameter( ValueFromPipeline = $true, ParameterSetName = 'ByUser' )] [System.String]$Identity, # Specifies the user account credentials to use when performing this task. [Parameter()] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty ) begin { $LogonInfo = Import-PSFPowerShellDataFile -Path $PSScriptRoot/PSPowerAdminTasks.psd1 Write-Verbose ('[{0:O}] Searching EventID : 4625 on Computer : {1} ' -f (get-date), $Computer) $WinEventArguments = @{ ComputerName = $Computer FilterHashtable = @{LogName = 'Security'; Id = 4625 } } if ($PSBoundParameters.ContainsKey('Credential')) { $WinEventArguments['Credential'] = $Credential } $lockoutEvents = $null Write-Verbose ('[{0:O}] Test if computer : {1} is alive ' -f (get-date), $Computer) if (Test-Connection -ComputerName $Computer -Quiet -Count 2) { try { $lockoutEvents = Get-WinEvent @WinEventArguments -ErrorAction Stop } catch { if ($_.Exception.Message -match "No events were found that match the specified selection criteria") { Write-Verbose ('[{0:O}] No logs found' -f (get-date)) } if ($Error[-1].Exception.Message -like "*elevated user rights*") { throw ('[{0:O}] You need an admin account. Please provide with the -Credential parameter' -f (get-date)) } } } else { throw ('[{0:O}] computer {1} is not alive' -f (get-date), $Computer) } if ($lockoutEvents) { Write-Verbose ('[{0:O}] {1} event found' -f (get-date), $lockoutEvents.Count) } else { throw ('[{0:O}] No event found' -f (get-date)) } } process { switch ($PSCmdlet.ParameterSetName) { All { Write-Verbose ('[{0:O}] Searching information for all user(s) ' -f (get-date)) Foreach ($Event in $lockoutEvents) { $eventXML = [xml]$event.ToXml() $Event | Select-Object -Property @( @{label = 'LockedUserName' ; Expression = {$eventXML.Event.EventData.Data[5].'#text'}} @{label = 'LogonType' ; Expression = {$LogonInfo.PrivateData.LogonType."$($eventXML.Event.EventData.Data[10].'#text')"}} @{label = 'LogonProcessName' ; Expression = {$eventXML.Event.EventData.Data[11].'#text'}} @{label = 'ProcessName' ; Expression = {$eventXML.Event.EventData.Data[18].'#text'}} @{label = 'FailureReason' ; Expression = {$LogonInfo.PrivateData.FailureReason."$($eventXML.Event.EventData.Data[8].'#text')"}} @{label = 'FailureStatus' ; Expression = {$LogonInfo.PrivateData.FailureType."$($eventXML.Event.EventData.Data[7].'#text')"}} @{label = 'FailureSubStatus' ; Expression = {$LogonInfo.PrivateData.FailureType."$($eventXML.Event.EventData.Data[9].'#text')"}} ) } } ByUser { Write-Verbose ('[{0:O}] Searching information for user : {1}' -f (get-date), $Identity) Foreach ($Event in $lockoutEvents) { $eventXML = [xml]$event.ToXml() If ($Event | Where-Object { $eventXML.Event.EventData.Data[5].'#text' -match $Identity }) { $Event | Select-Object -Property @( @{label = 'LockedUserName' ; Expression = {$eventXML.Event.EventData.Data[5].'#text'}} @{label = 'LogonType' ; Expression = {$LogonInfo.PrivateData.LogonType."$($eventXML.Event.EventData.Data[10].'#text')"}} @{label = 'LogonProcessName' ; Expression = {$eventXML.Event.EventData.Data[11].'#text'}} @{label = 'ProcessName' ; Expression = {$eventXML.Event.EventData.Data[18].'#text'}} @{label = 'FailureReason' ; Expression = {$LogonInfo.PrivateData.FailureReason."$($eventXML.Event.EventData.Data[8].'#text')"}} @{label = 'FailureStatus' ; Expression = {$LogonInfo.PrivateData.FailureType."$($eventXML.Event.EventData.Data[7].'#text')"}} @{label = 'FailureSubStatus' ; Expression = {$LogonInfo.PrivateData.FailureType."$($eventXML.Event.EventData.Data[9].'#text')"}} ) } } } } } end { } } #EndRegion '.\Public\Get-UserLockoutReason.ps1' 147 #Region '.\Public\Remove-OldUserProfile.ps1' 0 function Remove-OldUserProfile { [CmdletBinding(DefaultParameterSetName = "ByUserName")] param ( [Parameter(ParameterSetName = "ByUserName", Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [string[]]$UserName ) begin { } process { switch ($PSCmdlet.ParameterSetName) { "ByUserName" { foreach ($user in $UserName) { $registryKeyRemoved = $false Write-Verbose ('[{0:O}] remove user {1}' -f (Get-Date), $user) try { $ProfileList = Get-ChildItem -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList' -ErrorAction SilentlyContinue if ($ProfileList) { foreach ($profile in $ProfileList) { $ProfileSID = $profile.PSChildName $ProfilePath = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$ProfileSID").ProfileImagePath if ($ProfilePath -eq "$($env:systemdrive)\Users\$($user)") { Write-Verbose ('[{0:O}] remove ProfileList key {1}' -f (Get-Date), $ProfileSID) Remove-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$ProfileSID" -Recurse -Force -ErrorAction Stop $registryKeyRemoved = $true } } } } catch [System.Security.SecurityException] { Write-Error ('[{0:O}] Use a privileged user' -f (get-date)) } catch { Write-Output ('[{0:O}] ErrorID: {1}' -f (Get-Date), $_.Exception.Message) Write-Output ('[{0:O}] Exception: {1}' -f (Get-Date), $_.FullyQualifiedErrorId) Write-Output ('[{0:O}] Category: {1}' -f (Get-Date), (($_.Exception.GetType() | Select-Object -ExpandProperty UnderlyingSystemType).FullName)) } if ($registryKeyRemoved) { try { Remove-Item -Path "$($env:systemdrive)\Users\$($user)" -Recurse -Force -ErrorAction Stop } catch [System.Management.Automation.ItemNotFoundException] { Write-Warning ('[{0:O}] User {1} not found' -f (Get-Date), $user) } catch [System.UnauthorizedAccessException] { Write-Warning ('[{0:O}] Error during profile deletion, do it manually' -f (Get-Date), $user) } catch { Write-Output ('[{0:O}] ErrorID: {1}' -f (Get-Date), $_.Exception.Message) Write-Output ('[{0:O}] Exception: {1}' -f (Get-Date), $_.FullyQualifiedErrorId) Write-Output ('[{0:O}] Category: {1}' -f (Get-Date), (($_.Exception.GetType() | Select-Object -ExpandProperty UnderlyingSystemType).FullName)) } } } } } } end { } } #EndRegion '.\Public\Remove-OldUserProfile.ps1' 84 #Region '.\Public\Remove-UserFromGroup.ps1' 0 #take a list of users and for each users, check if the user is in a list of groups. If user is found in a group then remove the user from the group. function Remove-UserFromGroup { <# .SYNOPSIS Remove a user from a group .DESCRIPTION Remove one or more users from one or more groups .PARAMETER Users One user or more users to remove from one or more groups .PARAMETER Groups One or more groups to remove one or more users from .PARAMETER FilePathUser Path to a file containing one user per line .PARAMETER FilePathGroup Path to a file containing one group per line .PARAMETER Credential Credentials to use when performing this task .PARAMETER Log Log the operation into a file (in $env:temp by default) .PARAMETER Console Show the message in the console .EXAMPLE Remove-UserFromGroup -Users 'User1' -Groups 'Group1' Remove USer1 from Group1 .EXAMPLE Remove-UserFromGroup -Users 'User1','User2" -Groups 'Group1' Remove User1 and User2 from Group1 .EXAMPLE Remove-UserFromGroup -Users 'User1','User2" -Groups 'Group1','Group2' Remove User1 and User2 from Group1 and Group2 .EXAMPLE Remove-UserFromGroup -FilePathUser 'C:\Users.txt' -FilePathGroup 'C:\Groups.txt' Users.txt contains one user per line Groups.txt contains one group per line Remove users from groups based on a file containing users and a file containing groups .NOTES General notes #> [CmdletBinding(DefaultParameterSetName = 'ByUser')] param ( [Parameter(ParameterSetName = 'ByUser')] [string[]]$Users, [Parameter(ParameterSetName = 'ByUser')] [string[]]$Groups, [Parameter(ParameterSetName = 'ByFile')] [System.String]$FilePathUser, [Parameter(ParameterSetName = 'ByFile')] [System.String]$FilePathGroup, # Specifies the user account credentials to use when performing this task. [Parameter()] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty, [Parameter()] [switch]$log, [Parameter()] [switch]$Console ) begin { if ($log) { $LogPath = $env:Temp + '\Remove-UserFromGroup.csv' Write-Log -LogPath $LogPath -Message 'Starting Remove-UserFromGroup' -Severity Information -Console:$Console } } process { if ($PSCmdlet.ParameterSetName -eq 'ByFile') { $Users = Get-Content -Path $FilePathUser $Groups = Get-Content -Path $FilePathGroup } try { # Loop through each user foreach ($user in $users) { # Loop through each group foreach ($group in $groups) { if ($log) { write-log -LogPath $LogPath -Message "Searching user $($user) in group $($group)" -Severity Information -Console:$Console} # Check if the user is a member of the group $isMember = (Get-ADGroupMember -Identity $group -ErrorAction Stop | Where-Object { $_.SamAccountName -eq $user }) # If the user is a member of the group, remove them if ($isMember) { if ($log) { write-log -LogPath $LogPath -Message "User $($user) found in group $($group) => remove it" -Severity Information -Console:$Console} $Arguments = @{ Identity = $group Members = $user Confirm = $false ErrorAction = "Stop" } if ($PSBoundParameters.ContainsKey('Credential')) { $Arguments['Credential'] = $Credential } Remove-ADGroupMember @Arguments } } } } catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] { if ($log) { write-log -LogPath $LogPath -Message "group $($group) not found...." -Severity Error -Console:$Console} Write-Error ('[{0:O}] group {1} not found....' -f (Get-Date),$group) } catch [Microsoft.ActiveDirectory.Management.ADException] { if ($log) { write-log -LogPath $LogPath -Message "Insufficient access rights to perform the operation" -Severity Error -Console:$Console} Write-Error ('[{0:O}] Insufficient access rights to perform the operation' -f (Get-Date)) } catch { Write-Output ('[{0:O}] ErrorID: {1}' -f (Get-Date), $_.Exception.Message) Write-Output ('[{0:O}] Exception: {1}' -f (Get-Date), $_.FullyQualifiedErrorId) Write-Output ('[{0:O}] Category: {1}' -f (Get-Date), (($_.Exception.GetType() | Select-Object -ExpandProperty UnderlyingSystemType).FullName)) } } end { if ($log) { Write-Log -LogPath $LogPath -Message 'Ending Remove-UserFromGroup' -Severity Information -Console:$Console } } } #EndRegion '.\Public\Remove-UserFromGroup.ps1' 153 #Region '.\Public\Reset-AdminCountParameter.ps1' 0 function Reset-AdminCountParameter { [CmdletBinding(DefaultParameterSetName = "ByUser")] [OutputType([type])] param ( [Parameter(ParameterSetName = "ByUser")] [System.String[]]$Identity, [Parameter()] [System.String]$Server, [Parameter()] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty ) begin { $RootDomainSid = [String] (Get-ADForestRootDomain).DomainSID $CurrentDomainSid = [String] (Get-ADDomain).DomainSID } process { $Arguments = @{} if ($PSBoundParameters.ContainsKey('Credential')) { Write-Verbose ('[{0:O}] Add Credential to Argument list' -f (get-date)) $Arguments['Credential'] = $Credential } if ($PSBoundParameters.ContainsKey('Server')) { Write-Verbose ('[{0:O}] Add Server to Argument list' -f (get-date)) $Arguments['Server'] = $Server } $DefaultProtectedGroupSids = @('S-1-5-32-548', 'S-1-5-32-544', 'S-1-5-32-551', "$CurrentDomainSid-512", "$CurrentDomainSid-516", "$RootDomainSid-519", 'S-1-5-32-550', "$CurrentDomainSid-498", 'S-1-5-32-552', "$RootDomainSid-518", 'S-1-5-32-549') foreach ($group in $DefaultProtectedGroupSids) { Write-Verbose ('[{0:O}] Define default protected group {1}' -f (get-date),$group) $DefaultProtectedGroupSids += @(Get-ADGroupSubGroupMember $group -ErrorAction SilentlyContinue) } $ProtectedGroupActualUserMember = @() foreach ($Group in $DefaultProtectedGroupSids) { Write-Verbose ('[{0:O}] Seach user in default protected group {1}' -f (get-date),$group) $ProtectedGroupActualUserMember += Get-ADUser -Filter ("memberOf -RecursiveMatch"+"'"+((Get-ADGroup $Group).DistinguishedName -replace "'","''") +"'") -SearchBase (Get-ADDomain).DistinguishedName } switch ($PSCmdlet.ParameterSetName) { "ByUser" { try { foreach ($User in $Identity) { Write-Verbose ('[{0:O}] Work with {1}' -f (get-date),$User) $AdminCountUser = Get-ADObject -Filter {(Name -like $User)} -Properties @('admincount','memberof') if ($AdminCountUser.DistinguishedName -notin $ProtectedGroupActualUserMember.DistinguishedName) { Write-Verbose ('[{0:O}] Reset AdminCount for {1}' -f (get-date),$AdminCountUser.DistinguishedName) Set-ADObject -Identity $AdminCountUser.DistinguishedName -Clear admincount @Arguments Write-Verbose ('[{0:O}] Reset Security for {1}' -f (get-date),$AdminCountUser.DistinguishedName) if (($PSBoundParameters.ContainsKey('Server')) -and ($PSBoundParameters.ContainsKey('Credential'))) { $process = Invoke-Command -ComputerName $Arguments.Server -Credential $Arguments.Credential -ScriptBlock { param($username) & dsacls.exe "$($username)" /resetDefaultDACL /resetDefaultSACL Write-Output $LASTEXITCODE } -ArgumentList $AdminCountUser.DistinguishedName -AsJob $process | Wait-Job if (!($process | Receive-Job) -contains "The command completed successfully") { Write-Warning ('[{0:O}] Error during reseting security on {1}' -f (Get-Date),$adminCountUserList.DistinguishedName) } } else { Start-Process -FilePath "C:\Windows\System32\dsacls.exe"-ArgumentList "$($AdminCountUser.DistinguishedName) /resetDefaultDACL /resetDefaultSACL" } } else { Write-Verbose ('[{0:O}] {1} is member of a protected group' -f (get-date),$AdminCountUser.DistinguishedName) } } } catch { Write-Output ('[{0:O}] ErrorID: {1}' -f (Get-Date), $_.Exception.Message) Write-Output ('[{0:O}] Exception: {1}' -f (Get-Date), $_.FullyQualifiedErrorId) Write-Output ('[{0:O}] Category: {1}' -f (Get-Date), (($_.Exception.GetType() | Select-Object -ExpandProperty UnderlyingSystemType).FullName)) } } } } end { } } #EndRegion '.\Public\Reset-AdminCountParameter.ps1' 104 #Region '.\Public\Set-ChangePasswordAtNextLogon.ps1' 0 function Set-ChangePasswordAtNextLogon { <# .SYNOPSIS Force user to change password at next logon .DESCRIPTION Force user(s) passed as parameter to change password at next logon .PARAMETER Identity Name of user(s) to force to change password at next logon .PARAMETER DomainController Domain controler on which to perform the operation .PARAMETER Credential Credentials to use when performing the operation .PARAMETER Log Log the operation into a file .PARAMETER Console Show the message in the console .EXAMPLE Set-ChangePasswordAtNextLogon -Identity user1,user2,user3 .EXAMPLE Set-ChangePasswordAtNextLogon -Identity user1,user2,user3 -DomainController dc1 .EXAMPLE Set-ChangePasswordAtNextLogon -Identity user1,user2,user3 -Credential (Get-Credential) .EXAMPLE Set-ChangePasswordAtNextLogon -Identity user1,user2,user3 -Log .EXAMPLE Set-ChangePasswordAtNextLogon -Identity user1,user2,user3 -Console -Log .NOTES General notes #> [CmdletBinding(SupportsShouldProcess)] param ( # UserName [Parameter()] [System.String[]]$Identity, # Parameter help description [Parameter()] [System.String]$DomainController = (Get-ADDomainController -Discover -Service PrimaryDC).HostName[0], # Specifies the user account credentials to use when performing this task. [Parameter()] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty, [Parameter()] [switch]$log, [Parameter()] [switch]$Console ) begin { if ($log) { $LogPath = $env:Temp + '\Set-ChangePasswordAtNextLogon.csv' Write-Log -LogPath $LogPath -Message 'Starting Set-ChangePasswordAtNextLogon' -Severity Information -Console:$Console } } process { $count = 1 $Arguments = @{ ChangePasswordAtLogon = $True ErrorAction = "Stop" Server = $DomainController } if ($PSBoundParameters.ContainsKey('Credential')) { $Arguments['Credential'] = $Credential } foreach ($user in $Identity) { if ($log) { write-log -LogPath $LogPath -Message "Processing user $($count) of $($Identity.Count)" -Severity Information -Console:$Console} if ($log) { write-log -LogPath $LogPath -Message "Processing user $($user)" -Severity Information -Console:$Console} $count++ $Arguments['Identity'] = $user try { if ($PSCmdlet.ShouldProcess($user, 'Set-ADUser')) { if ($log) { write-log -LogPath $LogPath -Message "Processing user $($user)" -Severity Information -Console:$Console} Set-ADUser @Arguments } } catch [Microsoft.ActiveDirectory.Management.ADException] { if ($log) { write-log -LogPath $LogPath -Message "Insufficient access rights to perform the operation" -Severity Error -Console:$Console} Write-Error ('[{0:O}] Insufficient access rights to perform the operation' -f (Get-Date)) } catch { if ($log) { write-log -LogPath $LogPath -Message "$($_.Exception.Message)" -Severity Error -Console:$Console write-log -LogPath $LogPath -Message "$($_.FullyQualifiedErrorId)" -Severity Error -Console:$Console write-log -LogPath $LogPath -Message "$($_.Exception.GetType() | Select-Object -ExpandProperty UnderlyingSystemType).FullName)" -Severity Error } Write-Output ('[{0:O}] ErrorID: {1}' -f (Get-Date), $_.Exception.Message) Write-Output ('[{0:O}] Exception: {1}' -f (Get-Date), $_.FullyQualifiedErrorId) Write-Output ('[{0:O}] Category: {1}' -f (Get-Date), (($_.Exception.GetType() | Select-Object -ExpandProperty UnderlyingSystemType).FullName)) } } } end { if ($log) { Write-Log -LogPath $LogPath -Message 'Ending Set-ChangePasswordAtNextLogon' -Severity Information -Console:$Console } } } #EndRegion '.\Public\Set-ChangePasswordAtNextLogon.ps1' 129 #Region '.\Public\Set-LocalUserPassword.ps1' 0 function Set-LocalUserPassword { <# .SYNOPSIS Set the password of a local user account .DESCRIPTION Set the password of a local user account. Password pass as a plain text string will be converted to a secure string. .PARAMETER Username UserName of the local user account to set the password .PARAMETER Password Password of the local user account to set. Pass as a plain text string will be converted to a secure string. .PARAMETER ComputerName ComputerName where the local user account is located. Default is the local computer. .PARAMETER Credential Specifies the user account credentials to use when performing this task. .EXAMPLE Set-LocalUserPassword -Username "MyUser" -Password "P@sswOrd" -Credential ($MyAdminAccount) -ComputerName Myserver Set password of the local user account "MyUser" on the computer "Myserver" with the credential stored in the variable $MyAdminAccount .NOTES General notes #> [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [System.String]$Username, [Parameter(Mandatory = $true)] [System.String]$Password, [Parameter()] [System.String]$ComputerName = $env:COMPUTERNAME, # Specifies the user account credentials to use when performing this task. [Parameter()] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty ) begin { $ErrorActionPreference = 'Stop' } process { $NewSecurePwd = $Password | ConvertTo-SecureString -AsPlainText -Force try { if ($ComputerName -ne $env:COMPUTERNAME) { $Session = New-PSSession -ComputerName $ComputerName -Credential $Credential Invoke-Command -Session $Session -ScriptBlock { Get-LocalUser -Name $Using:Username | Set-LocalUser -Password $Using:NewSecurePwd } Remove-PSSession -Session $Session return } else { Get-LocalUser -Name $Username | Set-LocalUser -Password $NewSecurePwd return } } catch [Microsoft.PowerShell.Commands.UserNotFoundException] { Write-Error ('[{0:O}] User {1} not found' -f (Get-Date), $Username) } catch [Microsoft.PowerShell.Commands.AccessDeniedException] { Write-Error ('[{0:O}] Access denied, use account with suffisant privilege' -f (Get-Date)) } catch { Write-Output ('[{0:O}] ErrorID: {1}' -f (Get-Date), $_.Exception.Message) Write-Output ('[{0:O}] Exception: {1}' -f (Get-Date), $_.FullyQualifiedErrorId) Write-Output ('[{0:O}] Category: {1}' -f (Get-Date), (($_.Exception.GetType() | Select-Object -ExpandProperty UnderlyingSystemType).FullName)) } } end { $ErrorActionPreference = 'Continue' } } #EndRegion '.\Public\Set-LocalUserPassword.ps1' 96 #Region '.\Public\Set-SmbSigningConfiguration.ps1' 0 function Set-SmbSigningConfiguration { <# .SYNOPSIS Enable or disable EnableSecuritySignature and RequireSecuritySignature .DESCRIPTION Enable or disable EnableSecuritySignature and RequireSecuritySignature .PARAMETER ComputerName On or more computer name .PARAMETER EnableSecuritySignature Apply configuration (Enable by default) .PARAMETER RequireSecuritySignature Apply configuration (Enable by default) .PARAMETER Disabled Apply configuration disable to one or two parameters EnableSecuritySignature and RequireSecuritySignature .PARAMETER Credential Specifies the user account credentials to use when performing this task .PARAMETER log Log information in a file (in $env:Temp ) .PARAMETER Console Show information in console (need Log parameter) .EXAMPLE Set-SmbSigningConfiguration -ComputerName MyServer -EnableSecuritySignature -RequireSecuritySignature Enable the two parameters EnableSecuritySignature and RequireSecuritySignature on the computer MyServer .EXAMPLE Set-SmbSigningConfiguration -ComputerName MyServer -EnableSecuritySignature -RequireSecuritySignature -Disabled Disable the two parameters EnableSecuritySignature and RequireSecuritySignature on the computer MyServer .EXAMPLE Set-SmbSigningConfiguration -ComputerName MyServer -RequireSecuritySignature Enable only the parameter RequireSecuritySignature on the computer MyServer .EXAMPLE Set-SmbSigningConfiguration -ComputerName MyServer -RequireSecuritySignature -Disabled Disable only the parameter RequireSecuritySignature on the computer MyServer .NOTES General notes #> [CmdletBinding()] [OutputType([type])] param ( [Parameter(Mandatory=$true)] [System.String[]]$ComputerName, [Parameter()] [Switch]$EnableSecuritySignature, [Parameter()] [Switch]$RequireSecuritySignature, [Parameter()] [Switch]$Disabled, # Specifies the user account credentials to use when performing this task. [Parameter()] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty, [Parameter()] [switch]$log, [Parameter()] [switch]$Console ) begin { } process { if ($log) { $LogPath = $env:Temp + '\Set-SmbSigningConfiguration.csv' Write-Log -LogPath $LogPath -Message 'Starting Set-SmbSigningConfiguration' -Severity Information -Console:$Console } $Parameter = @{} if ($PSBoundParameters.ContainsKey('Credential')) { $Parameter['Credential'] = $Credential } foreach ($Computer in $ComputerName) { $Parameter['ComputerName'] = $Computer if ($log) { write-log -LogPath $LogPath -Message "ComputerName $($Computer)" -Severity Information -Console:$Console } if ($EnableSecuritySignature) { if ($Disabled) { if ($log) { write-log -LogPath $LogPath -Message "Disable Security Signature" -Severity Information -Console:$Console } Invoke-Command @Parameter -ScriptBlock { Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters' -Name 'EnableSecuritySignature' -Value 0 -Force Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters' -Name 'EnableSecuritySignature' -Value 0 -Force } } else { if ($log) { write-log -LogPath $LogPath -Message "Enable Security Signature" -Severity Information -Console:$Console } Invoke-Command @Parameter -ScriptBlock { Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters' -Name 'EnableSecuritySignature' -Value 1 -Force Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters' -Name 'EnableSecuritySignature' -Value 1 -Force } } } if ($RequireSecuritySignature) { if ($Disabled) { if ($log) { write-log -LogPath $LogPath -Message "Disable Require Security Signature" -Severity Information -Console:$Console } Invoke-Command @Parameter -ScriptBlock { Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters' -Name 'RequireSecuritySignature' -Value 0 -Force Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters' -Name 'RequireSecuritySignature' -Value 0 -Force } } else { if ($log) { write-log -LogPath $LogPath -Message "Enable Require Security Signature" -Severity Information -Console:$Console } Invoke-Command @Parameter -ScriptBlock { Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters' -Name 'RequireSecuritySignature' -Value 1 -Force Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters' -Name 'RequireSecuritySignature' -Value 1 -Force } } } } } end { if ($log) { Write-Log -LogPath $LogPath -Message 'Ending Set-SmbSigningConfiguration' -Severity Information -Console:$Console } } } #EndRegion '.\Public\Set-SmbSigningConfiguration.ps1' 166 #Region '.\Public\Update-LastPasswordDate.ps1' 0 function Update-LastPasswordDate { [CmdletBinding()] param ( [Parameter(ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)] [System.String[]]$Identity, # Specifies the user account credentials to use when performing this task. [Parameter()] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty, [Parameter()] [switch]$log, [Parameter()] [switch]$Console ) begin { if ($log) { $LogPath = $env:Temp + '\Update-LastPasswordDate.csv' Write-Log -LogPath $LogPath -Message 'Starting Update-LastPasswordDate' -Severity Information -Console:$Console } $Properties = "PwdLastSet", "PasswordLastSet", "SamAccountName" $Parameter = @{} if ($PSBoundParameters.ContainsKey('Credential')) { $Parameter['Credential'] = $Credential } } process { foreach ($User in $Identity) { $Parameter['Identity'] = $User $InfoUser = Get-ADUser @Parameter -Properties $Properties if ($log) { write-log -LogPath $LogPath -Message "UserName $($InfoUser.SamAccountName)" -Severity Information -Console:$Console } if ($log) { write-log -LogPath $LogPath -Message "Last password change date $($InfoUser.PasswordLastSet) " -Severity Information -Console:$Console } $InfoUser.PwdLastSet = 0 Set-ADUser -Instance $InfoUser $InfoUser.PwdLastSet = -1 Set-ADUser -Instance $InfoUser $InfoUser = Get-ADUser @Parameter -Properties $Properties if ($log) { write-log -LogPath $LogPath -Message "New last password change date $($InfoUser.PasswordLastSet)" -Severity Information -Console:$Console } } } end { if ($log) { Write-Log -LogPath $LogPath -Message 'Ending Update-LastPasswordDate' -Severity Information -Console:$Console } } } #EndRegion '.\Public\Update-LastPasswordDate.ps1' 70 |