FixPHSPasswordExpiry.ps1
<#PSScriptInfo
.VERSION 1.0 .GUID 9d7aace8-472b-4340-b0a2-291444196799 .AUTHOR Vikas Sukhija .COMPANYNAME TechWizard.cloud .COPYRIGHT Techwizard.cloud .TAGS .LICENSEURI .PROJECTURI https://techwizard.cloud/2021/02/17/password-hash-sync-password-expiry-set-to-never-expire/ .ICONURI .EXTERNALMODULEDEPENDENCIES .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES https://techwizard.cloud/2021/02/17/password-hash-sync-password-expiry-set-to-never-expire/ .PRIVATEDATA #> <# .DESCRIPTION Password HASH Sync - Password expiry Set to Never Expire #> ##################################################### param ( [string]$smtpserver = $(Read-Host "Enter SMTP Server"), [string]$from = $(Read-Host "Enter From Address"), [string]$erroremail = $(Read-Host "Enter Address for Report and Errors"), $countofchanges = "20", $logrecyclelimit = "60" ) ###################Functions######################### function New-FolderCreation { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$foldername ) $logpath = (Get-Location).path + "\" + "$foldername" $testlogpath = Test-Path -Path $logpath if($testlogpath -eq $false) { #Start-ProgressBar -Title "Creating $foldername folder" -Timer 10 $null = New-Item -Path (Get-Location).path -Name $foldername -Type directory } } #New-FolderCreation function Write-Log { [CmdletBinding()] param ( [Parameter(Mandatory = $true,ParameterSetName = 'Create')] [array]$Name, [Parameter(Mandatory = $true,ParameterSetName = 'Create')] [string]$Ext, [Parameter(Mandatory = $true,ParameterSetName = 'Create')] [string]$folder, [Parameter(ParameterSetName = 'Create',Position = 0)][switch]$Create, [Parameter(Mandatory = $true,ParameterSetName = 'Message')] [String]$message, [Parameter(Mandatory = $true,ParameterSetName = 'Message')] [String]$path, [Parameter(Mandatory = $false,ParameterSetName = 'Message')] [ValidateSet('Information','Warning','Error')] [string]$Severity = 'Information', [Parameter(ParameterSetName = 'Message',Position = 0)][Switch]$MSG ) switch ($PsCmdlet.ParameterSetName) { "Create" { $log = @() $date1 = Get-Date -Format d $date1 = $date1.ToString().Replace("/", "-") $time = Get-Date -Format t $time = $time.ToString().Replace(":", "-") $time = $time.ToString().Replace(" ", "") New-FolderCreation -foldername $folder foreach ($n in $Name) {$log += (Get-Location).Path + "\" + $folder + "\" + $n + "_" + $date1 + "_" + $time + "_.$Ext"} return $log } "Message" { $date = Get-Date $concatmessage = "|$date" + "| |" + $message +"| |" + "$Severity|" switch($Severity){ "Information"{Write-Host -Object $concatmessage -ForegroundColor Green} "Warning"{Write-Host -Object $concatmessage -ForegroundColor Yellow} "Error"{Write-Host -Object $concatmessage -ForegroundColor Red} } Add-Content -Path $path -Value $concatmessage } } } #Function Write-Log function Set-Recyclelogs { [CmdletBinding( SupportsShouldProcess = $true, ConfirmImpact = 'High')] param ( [Parameter(Mandatory = $true,ParameterSetName = 'Local')] [string]$foldername, [Parameter(Mandatory = $true,ParameterSetName = 'Local')] [Parameter(Mandatory = $true,ParameterSetName = 'Path')] [Parameter(Mandatory = $true,ParameterSetName = 'Remote')] [int]$limit, [Parameter(ParameterSetName = 'Local',Position = 0)][switch]$local, [Parameter(Mandatory = $true,ParameterSetName = 'Remote')] [string]$ComputerName, [Parameter(Mandatory = $true,ParameterSetName = 'Remote')] [string]$DriveName, [Parameter(Mandatory = $true,ParameterSetName = 'Remote')] [string]$folderpath, [Parameter(ParameterSetName = 'Remote',Position = 0)][switch]$Remote, [Parameter(Mandatory = $true,ParameterSetName = 'Path')] [ValidateScript({ if(-Not ($_ | Test-Path) ){throw "File or folder does not exist"} return $true })] [string]$folderlocation, [Parameter(ParameterSetName = 'Path',Position = 0)][switch]$Path ) switch ($PsCmdlet.ParameterSetName) { "Local" { $path1 = (Get-Location).path + "\" + "$foldername" if ($PsCmdlet.ShouldProcess($path1 , "Delete")) { Write-Host "Path Recycle - $path1 Limit - $limit" -ForegroundColor Green $limit1 = (Get-Date).AddDays(-"$limit") #for report recycling $getitems = Get-ChildItem -Path $path1 -recurse -file | Where-Object {$_.CreationTime -lt $limit1} ForEach($item in $getitems){ Write-Verbose -Message "Deleting item $($item.FullName)" Remove-Item $item.FullName -Force } } } "Remote" { $path1 = "\\" + $ComputerName + "\" + $DriveName + "$" + "\" + $folderpath if ($PsCmdlet.ShouldProcess($path1 , "Delete")) { Write-Host "Recycle Path - $path1 Limit - $limit" -ForegroundColor Green $limit1 = (Get-Date).AddDays(-"$limit") #for report recycling $getitems = Get-ChildItem -Path $path1 -recurse -file | Where-Object {$_.CreationTime -lt $limit1} ForEach($item in $getitems){ Write-Verbose -Message "Deleting item $($item.FullName)" Remove-Item $item.FullName -Force } } } "Path" { $path1 = $folderlocation if ($PsCmdlet.ShouldProcess($path1 , "Delete")) { Write-Host "Path Recycle - $path1 Limit - $limit" -ForegroundColor Green $limit1 = (Get-Date).AddDays(-"$limit") #for report recycling $getitems = Get-ChildItem -Path $path1 -recurse -file | Where-Object {$_.CreationTime -lt $limit1} ForEach($item in $getitems){ Write-Verbose -Message "Deleting item $($item.FullName)" Remove-Item $item.FullName -Force } } } } }# Set-Recycle logs function LaunchMSOL { [CmdletBinding()] param ( [Parameter(Mandatory = $false)] $Credential ) import-module msonline Write-Host "Enter MS Online Credentials" -ForegroundColor Green Connect-MsolService -Credential $Credential } #LaunchMSOL #####################Load variables and log############### $log = Write-Log -Name "FixPHSPasswordExpiry-Log" -folder "logs" -Ext "log" $ObjFilter = "(&(objectClass=user)(objectCategory=person)(!useraccountcontrol:1.2.840.113556.1.4.803:=2))" ##################get-credentials########################## Write-Log -Message "Get Crendetials for Admin ID for MSOnline Connection" -path $log if(Test-Path -Path ".\Password.xml"){ Write-Log -Message "Password file Exists" -path $log }else{ Write-Log -Message "Generate password" -path $log $Credential = Get-Credential $Credential | Export-Clixml ".\Password.xml" } ############################################################# $Credential = $null $Credential = Import-Clixml ".\Password.xml" ########################Start Script######################### Write-Log -Message "Start....................Script" -path $log $collusers = @() try{ Write-Log -Message "Fetch all Enabled Users with Password Expiry Status True" -path $log $collusers = Get-ADUser -LDAPFilter $ObjFilter -properties passwordexpired | Select DistinguishedName, SamAccountName, PasswordExpired, UserPrincipalName $collusers = $collusers.where{($_.passwordexpired -eq $true)} Write-Log -Message "Fetched users that have password Expiry status is True" -path $log } catch{ $exception = $_.Exception.Message Write-Log -Message $exception -path $log -Severity error Send-MailMessage -SmtpServer $smtpserver -From $from -To $erroremail -Subject "Error -FixPHSPasswordExpiry" -Body $($_.Exception.Message) exit } if(($collusers.count -le $countofchanges) -and ($collusers.count -gt 0)){ try{ LaunchMSOL -Credential $Credential Connect-AzureAD -Credential $Credential foreach($user in $collusers){ $upn = $user.UserPrincipalName $sam = $user.SamAccountName $msoluser = Get-MsolUser -UserPrincipalName $upn if($msoluser){ $azureaduser = Get-AzureADUser -ObjectId $msoluser.objectid if($azureaduser.PasswordProfile.ForceChangePasswordNextLogin -eq $true){ Write-Log -Message "Force Change password is already set for $upn - $sam" -path $log } else{ Write-Log -Message "Setting force change password for $upn - $sam" -path $log Set-MsolUserPassword -UserPrincipalName $upn -ForceChangePassword:$true -ForceChangePasswordOnly:$true } } else{ Write-Log -Message "$upn - $sam not found" -path $log } } Disconnect-AzureAD } catch{ $exception = $_.Exception.Message Write-Log -Message $exception -path $log -Severity error Send-MailMessage -SmtpServer $smtpserver -From $from -To $erroremail -Subject "Error - FixPHSPasswordExpiry" -Body $($_.Exception.Message) exit } } elseif($collusers.count -gt $countofchanges) { Write-Log -Message "Exiting Script as Count of changes exceeded $($collusers.count) more than $countofchanges" -path $log -Severity Error Send-MailMessage -SmtpServer $smtpserver -From $from -To $erroremail -Subject "Error Exiting Script as Count of changes exceeded FixPHSPasswordExpiry" -Body "Exiting Script as Count of changes exceeded $($collusers.count) more than $countofchanges" Exit } ########################Recycle reports & logs############################# Set-Recyclelogs -foldername "logs" -limit $logrecyclelimit -confirm:$false Write-Log -Message "Script............Finished" -path $log Send-MailMessage -SmtpServer $smtpserver -From $from -To $erroremail -Subject "Log - FixPHSPasswordExpiry" -Body "Log - FixPHSPasswordExpiry" -Attachments $log ########################################################################### |