elm-toolbox.psm1
|
function Clear-Folder { <# .SYNOPSIS This function uses Robocopy to mirror an empty folder over the top of the target directory, it is a VERY quick way of deleting a folder with a lot of subfolders and files. It also bypasses a lot of permission issues. .NOTES Name: Clear-Folder Author: Elliott Marter .EXAMPLE Clear-Folder -TargetDirectory C:\path\to\folder .LINK https://www.powershellgallery.com/profiles/elliottmarter #> [cmdletbinding(SupportsShouldProcess=$True)] param ( [Parameter(Position=0,mandatory=$true)] [string] $TargetDirectory ) # Create empty temp folder $EmptyDir = "$env:TEMP\empty_temp" New-Item -Path $EmptyDir -ItemType Directory -Force Write-Warning "You are about to erase everything in $TargetDirectory are you sure you want to continue" -WarningAction Inquire Write-Warning "Are you ABSOLUTELY certain?" -WarningAction Inquire takeown /a /r /d Y /f $TargetDirectory | Out-Null # use robocopy to mirror the empty directory over the top of the target directory robocopy $EmptyDir $TargetDirectory /MIR | Out-Null # remove empty temp folder and target folder Remove-Item $EmptyDir,$TargetDirectory -Force -Recurse | Out-Null Write-Output "$TargetDirectory has been removed" } Function Clear-RecycleBins { <# .SYNOPSIS This script will empty all $RECYCLE.BIN files on the selected volume .NOTES Name: Empty-RecycleBins Author: Elliott Marter .EXAMPLE Empty-RecycleBins -Volume D: .LINK https://www.powershellgallery.com/profiles/elliottmarter #> [CmdletBinding(SupportsShouldProcess)] param( [Parameter( Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 0 )] [string[]] $Volume ) BEGIN { $Bins = (Get-ChildItem -Path $Volume`: -Recurse -Force -Filter '$RECYCLE.BIN').FullName } PROCESS { foreach ($b in $Bins ) { Get-ChildItem -Path $b -Force -Recurse | Remove-Item -Force -Recurse -Verbose } } END {} } Function Disable-User { <# .SYNOPSIS This script will carry out some basic actions against an AD User to disable their access and process them as a leaver Actions include: DEFAULT - Disable AD Account - Change password - Set Mail Nickname (so that hide from GAL works) - Hide from GAL - Clear Title, Manager, Department and Company Fields - Set description to "Disabled: (date & time)" - Remove from all groups - Move to leaver OU - Set Mailbox to shared - Forward emails - Delegate emails OPTIONAL - Forward emails - Delegate mailbox .NOTES Name: Disable-User Author: Elliott Marter TO ADD Remove Licences .EXAMPLE Disable-User -Username john.smith -Forward mr.boss@contoso.com -Delegate mr.boss@contoso.com .LINK https://www.powershellgallery.com/profiles/elliottmarter #> [CmdletBinding()] param( [Parameter(Position=0,mandatory=$true)] [string] $Username, [string] $Forward, [string] $Delegate ) # Quick try catch to validate the username and confirm run try { $User = Get-ADUser -Identity $Username -Properties * } catch { throw "ERROR: Could not find $($Username), please try again" } $logfile = "$env:SystemDrive\elm_tools_logs\leaver_logs\$Username.txt" New-Item $logfile -Force -Confirm:$false | Out-Null Write-Output "logfile is here $logfile" # Call function to ask for Leaver OU if ($LeaverOU -eq $null) { $LeaverOU = (Select-ADOrganizationalUnit -Message "Select Leaver OU").DistinguishedName } $Confirm = Read-Host "$($User.Name) ($($User.UserPrincipalName)) will be disabled, Do you wish to contiune? Y/N" If ($Confirm -eq "Y") { # Disable Account Disable-ADAccount $User -Confirm:$false Write-Output "$($user.SamAccountName) account has been disabled" | Tee-Object $logfile -Append # Set New Password $Pass = (iwr https://www.dinopass.com/password/strong -UseBasicParsing).Content Set-ADAccountPassword -Identity $User -Reset -NewPassword (ConvertTo-SecureString -AsPlainText "$Pass" -Force) Write-Output "Password has been reset to $Pass" | Tee-Object $logfile -Append # Clear Title, Manager, Department and Company $Manager = (Get-Aduser -Identity ((Get-ADUser $User -Properties *).Manager)).Name Set-ADUser $User -Title $null -Manager $null -Department $null -Company $null Write-Output "Title = $($User.Title)" | Tee-Object $logfile -Append Write-Output "Manager = $Manager" | Tee-Object $logfile -Append Write-Output "Department = $($User.Department)" | Tee-Object $logfile -Append Write-Output "Company = $($User.Company)" | Tee-Object $logfile -Append Write-Output "Title, Manager, Department and Company fields have now been CLEARED" | Tee-Object $logfile -Append # Set description to date disabled $Description = "Disabled: $((get-date).ToString())" Set-ADUser $User -Description $Description Write-Output "Descripton set to $Description" | Tee-Object $logfile -Append # Remove From all groups $Groups = Get-AdPrincipalGroupMembership -Identity $User.SamAccountName | Where-Object -Property Name -Ne -Value 'Domain Users' Write-Output "$($user.SamAccountName) is being removed from the following groups" | Tee-Object $logfile -Append Write-Output $($Groups.Name) | Tee-Object $logfile -Append $Groups | Remove-AdGroupMember -Members $User -Confirm:$false try { # Set MailNickName & msExchHideFromAddressLists Set-ADObject $User -Replace @{MailNickName=$user.SamAccountName} Write-Output "Mailnickname set to $($user.SamAccountName)" | Tee-Object $logfile -Append Set-ADObject $User -Replace @{msExchHideFromAddressLists=$true} Write-Output "$($user.SamAccountName) hidden from GAL" | Tee-Object $logfile -Append } catch { Write-Output "Unable to set MailNickName & msExchHideFromAddressLists attribute (AD Schema may not have Exchange attributes??)" } # Move to Leaver OU Move-ADObject $User -TargetPath $LeaverOU Write-Output "$($user.SamAccountName) has been moved to $LeaverOU" | Tee-Object $logfile -Append # Set Mailbox to shared If ($Forward -or $Delegate) { Connect-ExchangeOnline Set-Mailbox -Identity $User.UserPrincipalName -Type Shared } # Set Mail forwarding If ($Forward) { Set-Mailbox -Identity $User.UserPrincipalName -DeliverToMailboxAndForward $true -ForwardingSMTPAddress "$Forward" Write-Output "Mail has been forwarded to $Forward" | Tee-Object $logfile -Append } # Set Mail delegation If ($Delegate) { Add-MailboxPermission -Identity $User.UserPrincipalName -User $Delegate -AccessRights FullAccess -InheritanceType All Write-Output "Mail has been delegated to $Delegate" | Tee-Object $logfile -Append } } } Function Export-Users { <# .SYNOPSIS Exports all enabled AD users, or members of a specific group, to a CSV file. .NOTES Name: Export-Users Author: Elliott Marter .EXAMPLE Export-Users -All Export-Users -Group "Finance" Export-Users -Group "Finance" -OutputPath "C:\Exports" #> [CmdletBinding(DefaultParameterSetName = 'all')] Param( [Parameter(ParameterSetName = 'all', Position = 0)] [Switch]$All, [Parameter(ParameterSetName = 'group', Position = 0, Mandatory)] [String]$Group, [Parameter()] [String]$OutputPath = "$Home\Desktop" ) $Date = Get-Date -UFormat %d-%m-%y try { if ($All) { $Users = Get-ADUser -Filter { Enabled -eq $true } -Properties Description $Users | Sort-Object Description, Name | Select-Object Name, @{Label = "Username"; Expression = { $_.SamAccountName } }, Description | Export-Csv -NoTypeInformation -Path (Join-Path $OutputPath "Full User Export $Date.csv") } if ($Group) { if (-not (Get-ADGroup -Identity $Group -ErrorAction SilentlyContinue)) { Write-Error "Group '$Group' not found." return } $Users = Get-ADGroupMember -Identity $Group -Recursive | Where-Object { $_.objectClass -eq 'user' } | ForEach-Object { Get-ADUser -Identity $_.SamAccountName -Properties Description } $Users | Where-Object { $_.Enabled -eq $true } | Sort-Object Description, Name | Select-Object Name, @{Label = "Username"; Expression = { $_.SamAccountName } }, @{Label = "Role"; Expression = { $_.Description } } | Export-Csv -NoTypeInformation -Path (Join-Path $OutputPath "$Group Users Export $Date.csv") } } catch { Write-Error "Export-Users failed: $_" } } Function Find-GPO { [CmdletBinding()] param( [Parameter(Mandatory = $true, Position = 0)] [string]$SearchString ) <# .SYNOPSIS Searches all GPOs in the domain for a specific string in their XML report. .DESCRIPTION This function retrieves all Group Policy Objects (GPOs) in the current domain and searches their XML reports for a specified string. It outputs the names of GPOs that contain the search string. .PARAMETER SearchString The string to search for within the GPO XML reports. .EXAMPLE Find-GPO -SearchString "Removable" This command searches all GPOs for the string "Removable" and outputs the names of matching GPOs. #> $matchList = @() $domainName = $env:USERDNSDOMAIN if (-not $domainName) { try { $domainName = (Get-ADDomain).DNSRoot } catch { throw "Unable to determine the current domain. Specify a domain or ensure AD tools are available." } } Import-Module GroupPolicy -ErrorAction SilentlyContinue $gpos = Get-GPO -All -Domain $domainName foreach ($gpo in $gpos) { $gpoReport = Get-GPOReport -Guid $gpo.Id -ReportType Xml if ($gpoReport -match [regex]::Escape($SearchString)) { $matchList += [string]$gpo.DisplayName Write-Host "Match: $($gpo.DisplayName)" -ForegroundColor Green } else { Write-Host "No match: $($gpo.DisplayName)" } } Write-Host "String `"$SearchString`" Found in:" -ForegroundColor Green if ($matchList.Count -gt 0) { $matchList | ForEach-Object { Write-Host $_ -ForegroundColor Green } } else { Write-Host "No matches found." -ForegroundColor Yellow } return $matchList } Function Grant-UserFolderPermissions { <# .SYNOPSIS This function will grant a user full access to their home and profile folders (from their AD Attribute) .NOTES Name: Grant-UserFolderPermissions Author: Elliott Marter .EXAMPLE Grant-UserFolderPermissions -Username john.wick .LINK https://www.powershellgallery.com/profiles/elliottmarter #> [cmdletbinding(SupportsShouldProcess=$True)] param( [Parameter( Mandatory = $true )] [string]$UserName ) $Domain = (Get-ADDomain).Name if ($Username) { try { $User = Get-ADUser -Filter {SamAccountName -eq $UserName} -Properties * $HomeFolder = $User.HomeDirectory $ProfileFolder = $User.ProfilePath $NTFS_Params = @{ Account = "$Domain\$UserName" AccessRights = "FullControl" AppliesTo = "ThisFolderSubfoldersAndFiles" } Write-Output "Fixing permissions for $HomeFolder" Add-NTFSAccess -Path $HomeFolder @NTFS_Params Write-Output "Fixing permissions for $ProfileFolder" Add-NTFSAccess -Path $ProfileFolder @NTFS_Params } Catch { Write-Error "$_.Exception.Message" } } } function Format-DisplayNames { <# .SYNOPSIS This function will format display names for all users in the selected OU It will ensure display names are "Firstname Lastname" with correct capitalization It bases this off of the first and last name attributes of the users .NOTES Name: Format-DisplayNames Author: Elliott Marter .EXAMPLE Format-DisplayNames .LINK https://www.powershellgallery.com/profiles/elliottmarter #> [cmdletbinding()] param () # get users in a certain OU $OU = Select-ADOrganizationalUnit -HideNewOUFeature | Select-Object DistinguishedName -ExpandProperty DistinguishedName $Users = Get-ADUser -Filter * -SearchBase $OU # loop through all users found foreach($U in $Users){ # assign variables $firstname = $U.givenname $surname = $U.surname $olddisplayname =$U.name # reassign variables with correct capitalization $firstname = $firstname.substring(0,1).ToUpper() $surname = $surname.substring(0,1).ToUpper()+$surname.substring(1).ToLower() # create the correct displayname $newdisplayname = $firstname + " $surname" # perform the rename action Set-ADUser -Identity $U -DisplayName $newdisplayname Rename-ADObject -Identity $U -NewName $newdisplayname Write-Host "Renamed $olddisplayname to $newdisplayname" -ForegroundColor Green } } function Get-InactiveComputers { <# .SYNOPSIS This function gets computers in the domain that have been inactivate (not logged on) for $DaysInactive Optionally specify the $Disable to disable the account and move them to the _DISABLED OU .NOTES Name: Get-InactivateComputers Author: Elliott Marter .EXAMPLE Get-InactivateComputers -DaysInactive 90 -DisableAccount .LINK https://www.powershellgallery.com/profiles/elliottmarter #> [cmdletbinding(SupportsShouldProcess=$True)] Param( [Parameter(Mandatory)] [int] $DaysInactive, [switch] $DisableAccount, [switch] $IncludeServers ) $Date = (Get-Date -UFormat %Y-%m-%d) $domain = (Get-ADDomain).DistinguishedName $oucheckname = "_DISABLED" $oucheck = [adsi]::Exists("LDAP://OU=$oucheckname,$domain") if ($oucheck -eq $false) { New-ADOrganizationalUnit -Name _DISABLED } $DisabledOU = (Get-ADOrganizationalUnit -Filter 'Name -eq "_DISABLED"').DistinguishedName if ($IncludeServers){ $Computers = Get-ADComputer -Filter * -Properties * | Where Enabled -EQ $true | Where LastLogonDate -NE $null | Where LastLogonDate -LT (Get-Date).AddDays(-$DaysInactive) } else { $Computers = Get-ADComputer -Filter * -Properties * | Where Enabled -EQ $true | Where LastLogonDate -NE $null | Where LastLogonDate -LT (Get-Date).AddDays(-$DaysInactive) | Where OperatingSystem -NotLike "*server*" } $Computers | Sort-Object LastLogonDate | Select-Object Name,LastLogonDate,OperatingSystem if ($DisableAccount) { foreach ($U in $computers) { $Description = (get-adcomputer -Identity $U.SamAccountName -Properties description).description $Note = " (Disabled: $(get-date -UFormat %d/%m/%y))" $NewDescription = $Description + $Note Set-ADcomputer -Identity $U.DistinguishedName -Description $NewDescription -Enabled $false Move-ADObject -Identity $U.DistinguishedName -TargetPath $DisabledOU Write-Verbose "Successfully disabled $($Item.Name)" } } } function Get-InactiveUsers { <# .SYNOPSIS This function gets users in the domain that have been inactivate (not logged on) for $DaysInactive Optionally specify the $Disable to disable the account and move them to the _DISABLED OU .NOTES Name: Get-InactivateUsers Author: Elliott Marter .EXAMPLE Get-InactivateUsers -DaysInactive 90 -DisableAccount .LINK https://www.powershellgallery.com/profiles/elliottmarter #> [cmdletbinding(SupportsShouldProcess=$True)] Param( [Parameter(Mandatory)] [int] $DaysInactive, [switch] $DisableAccount ) $Date = (Get-Date -UFormat %Y-%m-%d) $domain = (Get-ADDomain).DistinguishedName $oucheckname = "_DISABLED" $oucheck = [adsi]::Exists("LDAP://OU=$oucheckname,$domain") if ($oucheck -eq $false) { New-ADOrganizationalUnit -Name _DISABLED } $DisabledOU = (Get-ADOrganizationalUnit -Filter 'Name -eq "_DISABLED"').DistinguishedName $Users = Search-ADAccount -UsersOnly -AccountInactive -TimeSpan "$DaysInactive.00:00:00" | Where-Object { ($_.Enabled -eq $true) -and ($_.lastlogondate -ne $null) -and ($_.name -notlike "*admin*")} $Users | Sort-Object LastLogonDate | Select-Object Name,LastLogonDate if ($DisableAccount) { foreach ($U in $Users) { $Description = (get-aduser -Identity $U.SamAccountName -Properties description).description $Note = " (Disabled: $(get-date -UFormat %d/%m/%y))" $NewDescription = $Description + $Note Set-ADUser -Identity $U.DistinguishedName -Description $NewDescription -Enabled $false Move-ADObject -Identity $U.DistinguishedName -TargetPath $DisabledOU Write-Verbose "Successfully disabled $($Item.Name)" } } } Function Import-Users { <# .Synopsis Use this function to import users from a CSV file in to Active Directory .Description Users are imported in to an imported users OU, from there you can move them as you wish .Parameter CSV The path to a CSV file containing user data, CSV MUST have 3 columns, firstname, lastname & description .Parameter UsernameFormat Select the format you want for the usernames generated, currently johnd, john.d, jdoe, j.doe, john.doe are supported. .Parameter Usertype Select the type of user account, the function uses this to find the home directory (eg Home$\Staff) and also adds them to the corresponding security group .Parameter Homeshare Path to the Home$ share (eg \\DC01\Home$) .Parameter Profileshare Path to the Profile$ share (eg \\DC01\Profile$) .Parameter Password What password you want for the account, MUST comply with domain policy OR fine grained password policy. .Parameter RandomPassword Tells the function to use www.dinopass.com to generate random passwords for each account .Parameter Logpath What path to generate the log files, by default is current users desktop .EXAMPLE Import-Users -csv C:\users.csv -UsernameFormat -john.d -UserType Office #> [cmdletbinding(SupportsShouldProcess=$True)] #[CmdletBinding(DefaultParameterSetName='password')] Param( [Parameter( Mandatory=$true )] $csv, [Parameter( Mandatory=$true )] [ValidateSet('johnd','john.d','jdoe','j.doe','john.doe')] [string]$UsernameFormat, [Parameter( Mandatory=$true )] [ValidateSet('Staff','Office','Students')] [string]$UserType, [Parameter( ParameterSetName='password' )] [string]$Password, [Parameter( ParameterSetName='random' )] [switch]$RandomPassword, [string]$HomeShare = "\\$Env:COMPUTERNAME\Home$", [string]$ProfileShare = "\\$Env:COMPUTERNAME\Profile$", [string]$LogPath = "$env:USERPROFILE\Desktop\User Import Logs" ) $ErrorActionPreference = "Stop" # Setup logging $Log = "$LogPath\$(Get-Date -UFormat %Y-%m-%d) Import Log.csv" $FailLog = "$LogPath\$(Get-Date -UFormat %Y-%m-%d) FAILED Import Log.csv" if (!(Test-Path $Log)) { New-Item $Log, $FailLog -Force | Out-Null Set-Content -Path $Log -Value '"Full Name","UserName","Description","Password"' Set-Content -Path $FailLog -Value '"Full Name","UserName"' } # Store the data from the CSV in the $Users variable $Users = Import-csv $csv if ((Get-Content $csv)[0] -ne "firstname,lastname,description") { throw "Check your CSV Headers! Should be 'firstname,lastname,description'" } # Show current settings and require confirmation to continue Write-Host "Home Folder = $HomeShare\$UserType" -ForegroundColor Green Write-Host "Profile Folder = $ProfileShare\$UserType" -ForegroundColor Green Write-Host "Username Format = $UsernameFormat" -ForegroundColor Green Write-Warning "Please confirm these settings are correct" -WarningAction Inquire Write-Host "Log file: $LogPath" -ForegroundColor Cyan # Set some Variables $Domain = (Get-ADDomain).name $FullDomain = (Get-ADDomain).dnsroot $DomainRoot = (Get-ADDomain).DistinguishedName $HomePath = "$HomeShare\$UserType" $ProfilePath = "$ProfileShare\$UserType" # Tests for an "Imported Users" OU at root of domain and if it does not exist then it creates it $ImportOU = "OU=Imported Users,$DomainRoot" try { Get-ADOrganizationalUnit -Identity $ImportOU | Out-Null } catch { New-ADOrganizationalUnit -Name "Imported Users" -Path $DomainRoot } # Check Home & Profile paths exist if (!(Test-Path $HomePath)) { Throw "Could not find $HomePath!" } if (!(Test-Path $ProfilePath)) { Throw "Could not find $ProfilePath!" } # Loop through each row containing user details in the CSV file foreach ($User in $Users) { # Read user data from each field in each row and assign the data to a variable as below $Firstname = $User.firstname $Lastname = $User.lastname $FullName = "$Firstname $Lastname" $Description = $User.description # Select username format if ($UsernameFormat -eq "johnd") { $Username = $Firstname + $Lastname.substring(0,1) } if ($UsernameFormat -eq "john.d") { $Username = $Firstname + "." + $Lastname.substring(0,1) } if ($UsernameFormat -eq "jdoe") { $Username = $Firstname.substring(0,1) + $Lastname } if ($UsernameFormat -eq "j.doe") { $Username = $Firstname.substring(0,1) + "." + $Lastname } if ($UsernameFormat -eq "john.doe") { $Username = $Firstname + "." + $Lastname } # change to lower case and remove - and ' and spaces $Username = $Username.ToLower() -replace "[^a-zA-Z.]" # Generate a random password and make the first letter a capital if ($RandomPassword) { $Password = (Get-Culture).TextInfo.ToTitleCase((Invoke-WebRequest "http://www.dinopass.com/password/simple" -Verbose:$False | Select-Object Content -ExpandProperty Content)) } $PasswordSecure = $Password | ConvertTo-SecureString -AsPlainText -Force # Create splat of user params $UserParams = @{ SamAccountName = $Username UserPrincipalName = "$Username@$FullDomain" Name = $FullName GivenName = $Firstname Surname = $Lastname Path = $ImportOU ProfilePath = "$ProfilePath\$Username" HomeDrive = "H:" HomeDirectory = "$HomePath\$Username" Description = $Description ChangePasswordAtLogon = $true } # Create an object to make reporting later easier $UserObject = [PSCustomObject]@{ Name = $Fullname UserName = $Username Description = $Description Password = $Password } try { # Create the account New-ADUser @UserParams # Create user home folder New-Item -Name $Username -Path $HomePath -ItemType Directory | Out-Null # Set access rights on home folder Add-NTFSAccess -Path "$HomePath\$Username" -Account $Username -AccessRights FullControl # Add to groups Add-ADGroupMember -Identity $UserType -Members $Username # Set account password Set-ADAccountPassword -Identity $Username -Reset -NewPassword $PasswordSecure Set-ADUser -Identity $Username -Enabled $true -CannotChangePassword $false -ChangePasswordAtLogon $true # If student then change password requirements if ($UserType -eq "Students") { Set-ADUser -Identity $Username -Enabled $true -CannotChangePassword $true -ChangePasswordAtLogon $false -PasswordNeverExpires $true } # Write success message Write-Host "SUCCESS: Created $Username" -ForegroundColor Green # Log to file $UserObject | ConvertTo-Csv -NoTypeInformation | Select-Object -Skip 1 | Out-File -FilePath $Log -Append -encoding ASCII } catch { # Write failure message Write-Host "FAILURE: Unable to create $Username" -ForegroundColor Red # Log to file $UserObject | Select-Object Username | ConvertTo-Csv -NoTypeInformation | Select-Object -Skip 1 | Out-File -FilePath $FailLog -Append -encoding ASCII $_.Exception.Message | Out-File -FilePath $FailLog -Append -encoding ASCII continue } } } function Move-DisabledADObjectsToOU { [CmdletBinding(SupportsShouldProcess)] param ( [string]$OUName = '_DISABLED', [ValidateSet('Users','Computers','Both')] [string]$ObjectType = 'Both' ) $OU = Get-ADOrganizationalUnit -Filter "Name -eq '$OUName'" if (-not $OU) { Write-Error "OU '$OUName' not found." return } if ($ObjectType -in 'Users','Both') { Get-ADUser -Filter 'Enabled -eq $false' | Move-ADObject -TargetPath $OU.DistinguishedName -WhatIf:$WhatIfPreference } if ($ObjectType -in 'Computers','Both') { Get-ADComputer -Filter 'Enabled -eq $false' | Move-ADObject -TargetPath $OU.DistinguishedName -WhatIf:$WhatIfPreference } } function New-Password { [cmdletbinding(SupportsShouldProcess=$True)] param ( [Parameter()] [int]$Quantity = 1 ) $PasswordFile = "$env:USERPROFILE\Passwords.txt" if (Test-Path $PasswordFile) { Remove-Item $PasswordFile } $Colours = @('Red','Blue','Green','Yellow','Purple','Orange','Pink','Black','White','Silver') $Animals = @('Tiger','Panda','Eagle','Otter','Shark','Wolf','Falcon','Rabbit','Turtle','Lion') $Symbols = @('!','@','#','$','%') $counter = 0 $Passwords = 1..$Quantity | ForEach-Object { $counter++ Write-Progress -Activity 'Generating Passwords' -CurrentOperation "Password $_" -PercentComplete (($counter / $Quantity) * 100) $Colour = Get-Random -InputObject $Colours $Animal = Get-Random -InputObject $Animals $Numbers = -join ((0..9 | Get-Random -Count 2)) $Symbol = Get-Random -InputObject $Symbols "$Colour$Animal$Numbers$Symbol" } $Passwords } Function Ping-Test { [CmdletBinding()] param( [Parameter(Mandatory = $true)] $Target, [Parameter(Mandatory = $true)] $LogFileName ) # Base directory for log files $LogFolder = "$env:PUBLIC\Documents\ping_logs" New-Item $LogFolder -ItemType Directory -Force -ErrorAction SilentlyContinue | Out-Null $LogFile = Join-Path -Path $LogFolder -ChildPath "PingLog_$LogFileName.txt" Write-Host "Logfile is here: $LogFile" $bar = "*" * 30 Write-Host $bar Write-Host "DO NOT CLOSE THIS WINDOW - PING TEST RUNNING" Write-Host $bar # Infinite loop to keep pinging while ($true) { # Get the current date and time $Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" # Perform the ping and capture the result $PingResult = Test-Connection -ComputerName $Target -Count 1 -ErrorAction SilentlyContinue if ($PingResult) { # Log success message $LogMessage = "$Timestamp - Success: Reply from $($PingResult.Address) in $($PingResult.ResponseTime)ms" } else { # Log failure message $LogMessage = "$Timestamp - Failure: No response from $Target" } # Append the log message to the file Add-Content -Path $LogFile -Value $LogMessage # Wait for a specified interval (in seconds) before the next ping Start-Sleep -Seconds 10 } } function Remove-DisabledUsersFromGroups { [CmdletBinding()] param ( [string]$OU = "OU=_DISABLED" ) $Users = Get-ADUser -SearchBase $OU -Filter { Enabled -eq $false } foreach ($User in $Users) { Write-Host "Processing user: $($User.SamAccountName)" -ForegroundColor Cyan $Groups = Get-ADUser $User -Property MemberOf | Select-Object -ExpandProperty MemberOf foreach ($GroupDN in $Groups) { try { $Group = Get-ADGroup $GroupDN Remove-ADGroupMember -Identity $Group -Members $User -Confirm:$false -ErrorAction Stop Write-Host "Removed $($User.SamAccountName) from $($Group.Name)" -ForegroundColor Green } catch { Write-Warning "Failed to remove $($User.SamAccountName) from $GroupDN. Error: $_" } } } } Function Remove-OldDownloads { <# .SYNOPSIS This script will remove files older than x days within Redirected Downloads Folders Set PATH to the top level Redirected folder (e.g. D:\RedirecedFolders) .EXAMPLE Remove-OldDownloads -Path D:\RedirectedFolders -Days 14 #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$Path, [Parameter(Mandatory = $true)] [int]$Days ) Get-childitem $Path -Depth 1 -Directory -Filter "Downloads" | Get-ChildItem -Recurse -Force -Exclude *.ini | Where-Object LastWriteTime -LT (Get-Date).AddDays(-$Days) | Remove-Item -Force -Recurse -Verbose } Function Remove-UnlinkedGPOs { Import-Module grouppolicy Write-Warning "This script will remove all unlinked GPOs, Do you want to Continue (Y/N)?" -WarningAction Inquire Function IsNotLinked($xmldata){ If ($xmldata.GPO.LinksTo -eq $null) { Return $true } Return $false } $unlinkedGPOs = @() Get-GPO -All | ForEach { $gpo = ($_.ID) ; $_ | Get-GPOReport -ReportType xml | ForEach { If(IsNotLinked([xml]$_)){$unlinkedGPOs += $gpo} }} If ($unlinkedGPOs.Count -eq 0) { "No Unlinked GPO's Found. The script has not removed any GPOs" } Else { foreach ($GP in $unlinkedGPOs) { $GpToDelete = Get-GPO -guid $GP Write-Host "Removing $($GpToDelete.DisplayName)" -ForegroundColor Green Remove-GPO -Guid $GP -Verbose } } Write-Host "Finished running the script, $($unlinkedGPOs.Count) unused group policies were removed." }s function Schedule-Reboot { [CmdletBinding()] param( [Parameter(mandatory=$true)] [decimal]$Hours, [switch]$Shutdown ) if ($Hours -eq $null){ [decimal]$Hours = Read-Host "Perferm action in how many hours?" } [int]$seconds = $hours * 3600 if ($Shutdown) { shutdown.exe /s /f /t $seconds } else { shutdown.exe /r /f /t $seconds } } function Set-UPN { [cmdletbinding(SupportsShouldProcess=$True)] param ( [string] [Parameter(Mandatory=$true)] $OldSuffix, [string] [Parameter(Mandatory=$true)] $NewSuffix ) Import-Module ActiveDirectory $OU = Select-ADOrganizationalUnit -HideNewOUFeature | Select-Object DistinguishedName -ExpandProperty DistinguishedName $Users = Get-ADUser -Filter * -SearchBase $OU foreach ($U in $Users) { $NewUPN = $U.UserPrincipalName.Replace($OldSuffix,$NewSuffix) Set-ADUser -Identity $U.SamAccountName -UserPrincipalName $NewUPN } } Function Update-BootImage { <# .SYNOPSIS This function updates the boot image on a deployment server and automatically imports it in to WDS .NOTES Name: Update-BootImage Author: Elliott Marter .EXAMPLE Update-BootImage -DeploymentShare D:\DeploymentShare .LINK https://www.powershellgallery.com/profiles/elliottmarter - #> [CmdletBinding()] param( [Parameter( Mandatory = $true, Position = 0 )] [string[]] $DeploymentShare ) BEGIN { if (!(test-path $DeploymentShare)) { throw "Could not find $DeploymentShare please check again..." } # Import MDT Toolkit Import-Module "C:\Program Files\Microsoft Deployment Toolkit\bin\MicrosoftDeploymentToolkit.psd1" # Get all exisiting boot images and remove them Get-WdsBootImage | Remove-WdsBootImage } PROCESS { $DSItem = Get-Item $DeploymentShare $DSItem $DSName = $DSItem.name $DSName $DSPath = $DSItem.fullname $DSPath New-PSDrive -Name $DSName -PSProvider MDTProvider -Root $DSPath -Verbose Update-MDTDeploymentShare -Path "$($DSName):" -Verbose Import-WdsBootImage -NewImageName $DSName -NewDescription $DSName -Path "$DSPath\Boot\LiteTouchPE_x64.wim" -Verbose Get-PSDrive -Name $DSName | Remove-PSDrive -Verbose } END {} } |