New-AADConnectInboundRuleDisableExpiredAccounts.ps1
<#PSScriptInfo
.VERSION 2.6 .GUID 0e878ef7-98d6-4159-9b8b-e6a0870f0c81 .DESCRIPTION Create a new AADConnect inbound rule to disable cloud accounts for expired on-premises accounts. .AUTHOR Aaron Guilmette .COMPANYNAME Planet Technologies .COPYRIGHT 2023 .TAGS Azure AD Connect AADConnect disable expired account .LICENSEURI .PROJECTURI https://www.undocumented-features.com .ICONURI .EXTERNALMODULEDEPENDENCIES .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES THIS CODE AND ANY ASSOCIATED INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK OF USE, INABILITY TO USE, OR RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER. Author: Aaron Guilmette aguilmette@go-planet.com #> <# .SYNOPSIS Create new AAD Connect inbound rules to disable expired accounts .PARAMETER CreateTask Create a scheduled task that runs a full synchronization on all AD connectors every other week. .PARAMETER Domain Specify one or more domains to create the schedule for. .EXAMPLE .\New-AADConnectInboundRuleDisableExpiredAccounts.ps1 Create a new AAD Connect inbound rule for all AD connectors to disable expired accounts using the first available low precedence value. .EXAMPLE .\New-AADConnectInboundRuleDisableExpiredAccounts.ps1 -CreateTask -Domain contoso.com Create a new AAD Connect inbound rule for the AD connector matching contoso.com and establish a scheduled task to execute a full synhronization job every other week. .LINK https://aka.ms/aarongallery #> param ( [array]$Domain, [switch]$CreateTask ) # Collect all on-premises AD Connectors ## If $Domain is specified, select the matching connectors If ($Domain) { $DomainQuery = "^$($Domain -join "|")`$" [array]$ADConnectors = Get-ADSyncConnector | ? { $_.Subtype -notlike "*Windows Azure Active Directory*" -and $DomainQuery -match $_.Name } } else { [array]$ADConnectors = Get-ADSyncConnector | ? { $_.Subtype -notlike "*Windows Azure Active Directory*" } } # Create the $NewConnectors variable to contain list of newly created connectors [array]$NewConnectors = @() # Create an inbound rule with the lowest precedence for each connector If ($ADConnectors.Count -ge 1) { foreach ($Connector in $ADConnectors) { [string]$Identifier = [Guid]::NewGuid().ToString() [array]$AllRulesPrecedence = (Get-ADSyncRule).Precedence $Precedence = (($AllRulesPrecedence | Measure-Object -Minimum).Minimum - 1) $RuleName = "In from AD - Disable Expired Accounts - $($Connector.Name)" New-ADSyncRule ` -Name $RuleName ` -Identifier $Identifier ` -Description 'Inbound rule to disable expired accounts' ` -Direction 'Inbound' ` -Precedence $Precedence ` -PrecedenceAfter '00000000-0000-0000-0000-000000000000' ` -PrecedenceBefore '00000000-0000-0000-0000-000000000000' ` -SourceObjectType 'user' ` -TargetObjectType 'person' ` -Connector $Connector.Identifier.ToString() ` -LinkType 'Join' ` -SoftDeleteExpiryInterval 0 ` -ImmutableTag 'New-AADConnectInboundRuleDisableExpiredAccounts.1' ` -OutVariable syncRule | Out-Null # Transformation based on accountExpires # If AD accountExpires value is 0 or 9223372036854775807, the account is already configured to never expire # so flow accountEnabled "True." Otherwise, calculate the value from the accountExpires date and compare it # to the Now() date; if accountExpires compared to Now() is in the future, flow accountEnabled "True." If # accountExpires compared to Now() is in the past, flow accountEnabled "False." Add-ADSyncAttributeFlowMapping ` -SynchronizationRule $syncRule[0] ` -Destination 'accountEnabled' ` -FlowType 'Expression' ` -ValueMergeType 'Update' ` -Expression 'IIF(CStr([accountExpires])="0",True,(IIF(CStr([accountExpires])="9223372036854775807",True,IIF(DateFromNum([accountExpires])>(CDate(NumFromDate(Now()))),True,False))))' ` -OutVariable syncRule | Out-Null # Create the scoping rule conditions New-Object ` -TypeName 'Microsoft.IdentityManagement.PowerShell.ObjectModel.ScopeCondition' ` -ArgumentList 'userAccountControl', '2', 'ISBITNOTSET' ` -OutVariable condition0 | Out-Null # Add the scoping rule conditions to the rule object Add-ADSyncScopeConditionGroup ` -SynchronizationRule $syncRule[0] ` -ScopeConditions @($condition0[0]) ` -OutVariable syncRule | Out-Null # Create the rule Add-ADSyncRule -SynchronizationRule $syncRule[0] | Out-Null # Get-ADSyncRule -Identifier $Identifier $NewConnectors += "$($RuleName), $($Identifier)" } Write-Output "New rules created:" $NewConnectors # Create bi-weekly scheduled task If ($Create) { If (!(Get-ScheduledJob "AAD Connect Full Sync" -ea SilentlyContinue) ) { $Trigger = New-JobTrigger -Weekly -At "11:00 PM" -DaysOfWeek Saturday -WeeksInterval 2 Register-ScheduledJob -Name "AAD Connect Full Sync" -ScriptBlock { Get-ADSyncConnector | ? { $_.Subtype -notlike "*Windows Azure Active Directory*" } | % { Invoke-ADSyncRunProfile -ConnectorName $_.Name -RunProfileName 'Full Synchronization' } } -Trigger $Trigger | Out-Null } } } Else { Write-Output "No connectors matching $($Domain) found." } |