Last active
October 26, 2021 14:56
Star
You must be signed in to star a gist
Poll Azure AD Connect for the current sync status and initiate a delta sync cycle.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
Azure AD Sync Status Console | |
Allows you to initiate a delta sync and view the status using the console. | |
Requires Microsoft Azure AD Connect, available at http://go.microsoft.com/fwlink/?LinkId=615771 | |
Tested with Azure AD Connect 1.1.486.0, PowerShell 4.0, and Windows Server 2012 R2 Standard 6.3 build 9600 (64-bit). | |
11:27 AM 01/03/2018 - Initial version. | |
#> | |
#Requires -Version 4 | |
Set-StrictMode -Version 4 | |
#region private functions | |
<# | |
.Synopsis | |
Main entry point for the script. | |
.EXAMPLE | |
Start the script. | |
Main | |
#> | |
function Main() | |
{ | |
$quit = $false | |
$syncStart = $null | |
$msSleep = 1000 | |
$howToMsg = 'Press [q] to quit, press [d] to perform a delta sync.' | |
Write-Host -Object $howToMsg | |
While ($quit -ne $true) | |
{ | |
$syncStatus = Get-ADSyncConnectorRunStatus | |
if ($null -ne $syncStatus) | |
{ | |
# Increase the sleep time to account for the delay between switching from | |
# Windows Azure AD (Microsoft) and AD Domain Services sync jobs. | |
if ($null -eq $syncStart) | |
{ | |
$syncStart = Get-Date | |
$msSleep = 5000 | |
} | |
# TODO: Check MicrosoftIdentityIntegrationServer and get actual item counts. | |
Write-Progress -Activity $syncStatus.ConnectorName -Status $syncStatus.RunState -PercentComplete (Get-Random -Minimum 1 -Maximum 99) | |
} | |
else | |
{ | |
# Display sync time information and decrease the sleep time to allow for | |
# faster keyboard input detection. | |
if ($null -ne $syncStart) | |
{ | |
Write-Progress -Activity 'Sync task' -Status 'Complete' -Completed | |
$execTime = (Get-Date) - $syncStart | |
Write-Host -Object "$($execTime.TotalSeconds) seconds" -ForegroundColor Green | |
$syncStart = $null | |
$msSleep = 1000 | |
Write-Host -Object $howToMsg | |
} | |
# Detect but do not wait for keyboard input. | |
if ([System.Console]::KeyAvailable) | |
{ | |
$keyInfo = [System.Console]::ReadKey() | |
if ($keyInfo.key -eq 'Q') | |
{ | |
$quit = $true | |
# Skip sleep command. | |
$msSleep = 0 | |
} | |
if ($keyInfo.key -eq 'D') | |
{ | |
Start-ADSyncSyncCycle -PolicyType Delta | |
} | |
} | |
Write-Host -Object '.' -NoNewline | |
} | |
Start-Sleep -Milliseconds $msSleep | |
} | |
} | |
#endregion | |
Main |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
Azure AD Sync Status WPF | |
Allows you to initiate a delta sync and view the status using Windows Presentation Framework. | |
Requires Microsoft Azure AD Connect, available at http://go.microsoft.com/fwlink/?LinkId=615771 | |
Tested with Azure AD Connect 1.1.486.0, PowerShell 4.0, and Windows Server 2012 R2 Standard 6.3 build 9600 (64-bit). | |
03:50 PM 01/02/2018 - Initial version. | |
#> | |
#Requires -Version 4 | |
Set-StrictMode -Version 4 | |
#region private functions | |
<# | |
.Synopsis | |
Displays the current sync status reported by Azure AD Connect. | |
UI controls are also enabled/disabled based on sync status. | |
.EXAMPLE | |
Check the sync status using the default 5 seconds. | |
Start-SyncStatusMonitorJob | |
.EXAMPLE | |
Check the sync status using a wait time of 300 milliseconds. | |
Start-SyncStatusMonitorJob -WaitMilliseconds 300 | |
#> | |
function Start-SyncStatusMonitorJob | |
{ | |
Param | |
( | |
# Amount in milliseconds to wait before checking the sync status. | |
[int] | |
$WaitMilliseconds = 5000 | |
) | |
$Script:syncHash.Add('WaitMilliseconds', $WaitMilliseconds) | |
# Helps prevent UI blocking by having UI updates performed on a different thread. | |
# https://github.com/1RedOne/BlogPosts/blob/master/GUI%20Part%20V/PowerShell-GUI%20with%20Runspace%20Snippet.ps1 | |
$runspace = [RunspaceFactory]::CreateRunspace() | |
$runspace.Open() | |
$runspace.SessionStateProxy.SetVariable('syncHash', $Script:syncHash) | |
$powershell = [PowerShell]::Create() | |
$powershell.Runspace = $runspace | |
$powershell.AddScript({ | |
Import-Module -Name ADSync | |
While ($syncHash.quitApp -eq $false) | |
{ | |
$syncHash.frmMain.Dispatcher.Invoke([action]{ | |
$syncState = Get-ADSyncConnectorRunStatus | |
if ($null -ne $syncState) | |
{ | |
$syncHash.lblSyncStatus.Content = $syncState.ConnectorName + ': '+ $syncState.RunState | |
$syncHash.pbSyncStatus.IsIndeterminate = $true | |
$syncHash.btnStartDeltaSync.IsEnabled = $false | |
} | |
# Only enable the sync button after a sync job has completed. | |
elseif ($null -eq $syncState -and $syncHash.lblSyncStatus.Content -ne 'Waiting for sync to start') | |
{ | |
$syncHash.lblSyncStatus.Content = 'No sync in progress' | |
$syncHash.pbSyncStatus.IsIndeterminate = $false | |
$syncHash.btnStartDeltaSync.IsEnabled = $true | |
} | |
}) | |
Start-Sleep -Milliseconds $syncHash.WaitMilliseconds | |
} | |
}) | Out-Null | |
$handle = $powershell.BeginInvoke() | |
} | |
<# | |
.Synopsis | |
Main entry point for the script. | |
.EXAMPLE | |
Start the script UI. | |
Main | |
#> | |
function Main() | |
{ | |
Write-Debug -Message 'Start Main()' | |
Add-Type -AssemblyName PresentationFramework | |
Import-Module -Name ADSync | |
# Used to pass variables to background UI update job. | |
$Script:syncHash = [Hashtable]::Synchronized(@{}) | |
# Define main WPF window with XAML. | |
# https://mcpmag.com/articles/2016/04/28/building-ui-using-powershell.aspx | |
[xml]$xamlMain = @' | |
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |
xmlns:local="clr-namespace:AadStatus" | |
Title="AAD Sync Status" Height="115" Width="320"> | |
<Grid Background="#FF343434"> | |
<Label Content="Status:" HorizontalAlignment="Left" VerticalAlignment="Top" Background="{x:Null}" Foreground="White" FontSize="8"/> | |
<Label x:Name="lblSyncStatus" Content="No sync in progress" Margin="0,10,5,0" VerticalAlignment="Top" Foreground="White"/> | |
<Button x:Name="btnStartDeltaSync" Content="Start Delta Sync" Margin="0,0,5,22" VerticalAlignment="Bottom" HorizontalAlignment="Right" Width="108"/> | |
<ProgressBar x:Name="pbSyncStatus" Margin="5,0,5,5" Height="9" VerticalAlignment="Bottom"/> | |
</Grid> | |
</Window> | |
'@ | |
$reader = New-Object -TypeName System.Xml.XmlNodeReader -ArgumentList $xamlMain | |
$Script:frmMain = [Windows.Markup.XamlReader]::Load($reader) | |
$Script:syncHash.Add('quitApp', $false) | |
$Script:syncHash.Add('frmMain', $Script:frmMain) | |
# Ensure controls with a defined name are accessible via local script variable and sync hash. | |
$xamlMain.SelectNodes("//*[@*[contains(translate(name(.), 'n', 'N'), 'Name')]]")|% { | |
Write-Debug -Message ('Creating variable $Script:' + $_.Name) | |
New-Variable -Name $_.Name -Value $Script:frmMain.FindName($_.Name) -Scope Script -Force | |
$Script:syncHash.Add($_.Name, $Script:frmMain.FindName($_.Name)) | |
} | |
$Script:btnStartDeltaSync.Add_Click({ | |
Write-Debug -Message ('btnStartDeltaSync.Add_Click') | |
# Allow sync button to be pressed once. | |
$Script:syncHash['btnStartDeltaSync'].IsEnabled = $false | |
$Script:syncHash['lblSyncStatus'].Content = 'Waiting for sync to start' | |
Start-ADSyncSyncCycle -PolicyType Delta | |
}) | |
Start-SyncStatusMonitorJob | |
$Script:frmMain.ShowDialog() | Out-Null | |
$Script:syncHash.quitApp = $true | |
} | |
#endregion | |
Main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment