New-AADConnectInboundRuleDisableExpiredAccounts.ps1
<#PSScriptInfo
.VERSION 2.3 .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 Create Create a scheduled task. .PARAMETER Domain Specify one or more domains to create the schedule for. .EXAMPLE .\New-AADConnectInboundRuleDisableExpiredAccounts.ps1 Create a new AAD Connect inbound rule to disable expired accounts using the first available low precedence value .LINK https://aka.ms/aarongallery #> param ( [array]$Domain, [switch]$Create ) # 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 If ($Create) { $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." } |