Created
April 1, 2026 14:57
-
-
Save Calvindd2f/14ddbc24c6793c0c4df59f8acc07f7db to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| #requires -Version 5.1 | |
| [CmdletBinding()] | |
| param( | |
| [Parameter()] | |
| [string]$OutputPath = "$env:USERPROFILE\Desktop\UserWorkspaceState_$($env:COMPUTERNAME)_$(Get-Date -Format 'yyyyMMdd_HHmmss').json", | |
| [switch]$IncludePrinters = $true, | |
| [switch]$IncludeDriverExportManifest = $true | |
| ) | |
| Set-StrictMode -Version Latest | |
| $ErrorActionPreference = 'Continue' | |
| function Get-RegistryKeyProperties { | |
| param([Parameter(Mandatory)][string]$Path) | |
| try { Get-ItemProperty -Path $Path -ErrorAction Stop } catch { $null } | |
| } | |
| function Get-RegistryDefaultValue { | |
| param([Parameter(Mandatory)][string]$Path) | |
| try { (Get-Item -Path $Path -ErrorAction Stop).GetValue('') } catch { $null } | |
| } | |
| function Convert-ToSyncUrl { | |
| param( | |
| [string]$SiteId, | |
| [string]$WebId, | |
| [string]$ListId, | |
| [string]$TenantId, | |
| [string]$WebUrl, | |
| [string]$SiteUrl, | |
| [string]$WebTitle, | |
| [string]$ListTitle, | |
| [string]$UserEmail | |
| ) | |
| $map = [ordered]@{ | |
| siteId = $SiteId | |
| webId = $WebId | |
| listId = $ListId | |
| tenantId = $TenantId | |
| webUrl = $WebUrl | |
| siteUrl = $SiteUrl | |
| webTitle = $WebTitle | |
| listTitle = $ListTitle | |
| userEmail = $UserEmail | |
| } | |
| $pairs = foreach ($entry in $map.GetEnumerator()) { | |
| if ([string]::IsNullOrWhiteSpace([string]$entry.Value)) { continue } | |
| '{0}={1}' -f $entry.Key, [uri]::EscapeDataString([string]$entry.Value) | |
| } | |
| if (-not $pairs) { return $null } | |
| 'odopen://sync/?' + ($pairs -join '&') | |
| } | |
| function Get-OneDriveAccounts { | |
| $root = 'HKCU:\Software\Microsoft\OneDrive\Accounts' | |
| if (-not (Test-Path $root)) { return @() } | |
| foreach ($key in Get-ChildItem -Path $root -ErrorAction SilentlyContinue) { | |
| $props = Get-RegistryKeyProperties -Path $key.PSPath | |
| if (-not $props) { continue } | |
| [pscustomobject]@{ | |
| AccountKey = $key.PSChildName | |
| UserEmail = $props.UserEmail | |
| DisplayName = $props.DisplayName | |
| UserFolder = $props.UserFolder | |
| TenantID = $props.TenantID | |
| TenantName = $props.TenantName | |
| UrlNamespace = $props.UrlNamespace | |
| ServiceEndpointUri = $props.ServiceEndpointUri | |
| IsBusiness = ($key.PSChildName -like 'Business*') | |
| RegistryPath = $key.PSPath | |
| } | |
| } | |
| } | |
| function Get-OneDriveScopeMountCache { | |
| $accountsRoot = 'HKCU:\Software\Microsoft\OneDrive\Accounts' | |
| if (-not (Test-Path $accountsRoot)) { return @() } | |
| $results = New-Object System.Collections.Generic.List[object] | |
| foreach ($accountKey in Get-ChildItem -Path $accountsRoot -ErrorAction SilentlyContinue) { | |
| $cachePath = Join-Path $accountKey.PSPath 'ScopeIdToMountPointPathCache' | |
| if (-not (Test-Path $cachePath)) { continue } | |
| try { | |
| $cacheKey = Get-Item -Path $cachePath -ErrorAction Stop | |
| $valueNames = $cacheKey.GetValueNames() | |
| } | |
| catch { | |
| continue | |
| } | |
| foreach ($valueName in $valueNames) { | |
| try { $mountPoint = $cacheKey.GetValue($valueName) } catch { $mountPoint = $null } | |
| $results.Add([pscustomobject]@{ | |
| AccountKey = $accountKey.PSChildName | |
| ScopeId = $valueName | |
| MountPoint = $mountPoint | |
| RegistryPath = $cachePath | |
| }) | |
| } | |
| } | |
| $results | |
| } | |
| function Get-SyncEngineProviders { | |
| $root = 'HKCU:\Software\SyncEngines\Providers\OneDrive' | |
| if (-not (Test-Path $root)) { return @() } | |
| foreach ($providerKey in Get-ChildItem -Path $root -ErrorAction SilentlyContinue) { | |
| $props = Get-RegistryKeyProperties -Path $providerKey.PSPath | |
| if (-not $props) { continue } | |
| $syncType = if ( | |
| ($props.UrlNamespace -match 'sharepoint\.com') -or | |
| ($props.SiteURL -match 'sharepoint\.com') -or | |
| ($props.WebURL -match 'sharepoint\.com') | |
| ) { | |
| 'SharePoint' | |
| } | |
| elseif ( | |
| ($props.UrlNamespace -match 'onedrive') -or | |
| ($providerKey.PSChildName -match 'OneDrive') | |
| ) { | |
| 'OneDrive' | |
| } | |
| else { | |
| 'Unknown' | |
| } | |
| [pscustomobject]@{ | |
| SyncType = $syncType | |
| RegistryKey = $providerKey.PSChildName | |
| DisplayName = $props.DisplayName | |
| MountPoint = $props.MountPoint | |
| UrlNamespace = $props.UrlNamespace | |
| LibraryType = $props.LibraryType | |
| SiteID = $props.SiteID | |
| WebID = $props.WebID | |
| ListID = $props.ListID | |
| TenantID = $props.TenantID | |
| SiteURL = $props.SiteURL | |
| WebURL = $props.WebURL | |
| LibraryURL = $props.LibraryURL | |
| WebTitle = $props.WebTitle | |
| ListTitle = $props.ListTitle | |
| UserEmail = $props.UserEmail | |
| ResourceID = $props.ResourceID | |
| CID = $props.CID | |
| SyncUrl = Convert-ToSyncUrl ` | |
| -SiteId $props.SiteID ` | |
| -WebId $props.WebID ` | |
| -ListId $props.ListID ` | |
| -TenantId $props.TenantID ` | |
| -WebUrl $props.WebURL ` | |
| -SiteUrl $props.SiteURL ` | |
| -WebTitle $props.WebTitle ` | |
| -ListTitle $props.ListTitle ` | |
| -UserEmail $props.UserEmail | |
| RegistryPath = $providerKey.PSPath | |
| LastWriteTime = $providerKey.LastWriteTime | |
| } | |
| } | |
| } | |
| function Get-MappedDrives { | |
| $results = New-Object System.Collections.Generic.List[object] | |
| try { | |
| $logicalDisks = Get-CimInstance Win32_LogicalDisk -Filter "DriveType = 4" -ErrorAction Stop | |
| foreach ($disk in $logicalDisks) { | |
| $results.Add([pscustomobject]@{ | |
| DriveLetter = $disk.DeviceID | |
| RemotePath = $disk.ProviderName | |
| Source = 'Win32_LogicalDisk' | |
| FileSystem = $disk.FileSystem | |
| VolumeName = $disk.VolumeName | |
| Persistent = $null | |
| UserName = $null | |
| }) | |
| } | |
| } | |
| catch {} | |
| $networkKey = 'HKCU:\Network' | |
| if (Test-Path $networkKey) { | |
| foreach ($key in Get-ChildItem -Path $networkKey -ErrorAction SilentlyContinue) { | |
| $props = Get-RegistryKeyProperties -Path $key.PSPath | |
| if (-not $props) { continue } | |
| $exists = $results | Where-Object { | |
| $_.DriveLetter -eq ($key.PSChildName + ':') -and $_.RemotePath -eq $props.RemotePath | |
| } | |
| if ($exists) { continue } | |
| $results.Add([pscustomobject]@{ | |
| DriveLetter = $key.PSChildName + ':' | |
| RemotePath = $props.RemotePath | |
| Source = 'HKCU:\Network' | |
| FileSystem = $null | |
| VolumeName = $null | |
| Persistent = $true | |
| UserName = $props.UserName | |
| }) | |
| } | |
| } | |
| try { | |
| $psDrives = Get-PSDrive -PSProvider FileSystem | Where-Object { $_.DisplayRoot -or $_.Root -match '^\\\\' } | |
| foreach ($drv in $psDrives) { | |
| $driveLetter = if ($drv.Name -match '^[A-Z]$') { $drv.Name + ':' } else { $null } | |
| $remotePath = if ($drv.DisplayRoot) { $drv.DisplayRoot } else { $drv.Root } | |
| $exists = $results | Where-Object { | |
| $_.DriveLetter -eq $driveLetter -and $_.RemotePath -eq $remotePath | |
| } | |
| if ($exists) { continue } | |
| $results.Add([pscustomobject]@{ | |
| DriveLetter = $driveLetter | |
| RemotePath = $remotePath | |
| Source = 'PSDrive' | |
| FileSystem = 'FileSystem' | |
| VolumeName = $null | |
| Persistent = $null | |
| UserName = $null | |
| }) | |
| } | |
| } | |
| catch {} | |
| $results | Sort-Object DriveLetter, RemotePath -Unique | |
| } | |
| function Get-ExplorerNamespaces { | |
| $roots = @( | |
| 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Desktop\NameSpace', | |
| 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace' | |
| ) | |
| foreach ($root in $roots) { | |
| if (-not (Test-Path $root)) { continue } | |
| foreach ($key in Get-ChildItem -Path $root -ErrorAction SilentlyContinue) { | |
| [pscustomobject]@{ | |
| NamespaceRoot = $root | |
| CLSIDKey = $key.PSChildName | |
| DisplayName = Get-RegistryDefaultValue -Path $key.PSPath | |
| RegistryPath = $key.PSPath | |
| } | |
| } | |
| } | |
| } | |
| function Get-PrintersForCapture { | |
| if (-not $IncludePrinters) { return @() } | |
| $printers = @() | |
| try { | |
| $printers = Get-CimInstance Win32_Printer -ErrorAction Stop | ForEach-Object { | |
| $isSharedConnection = $false | |
| $connectionPath = $null | |
| if ($_.Network -and $_.Name -match '^\\\\') { | |
| $isSharedConnection = $true | |
| $connectionPath = $_.Name | |
| } | |
| elseif ($_.SystemName -and $_.ShareName -and $_.SystemName -ne $env:COMPUTERNAME) { | |
| $isSharedConnection = $true | |
| $connectionPath = "\\{0}\{1}" -f $_.SystemName.TrimStart('\'), $_.ShareName | |
| } | |
| [pscustomobject]@{ | |
| Name = $_.Name | |
| DriverName = $_.DriverName | |
| PortName = $_.PortName | |
| Network = [bool]$_.Network | |
| Shared = [bool]$_.Shared | |
| ShareName = $_.ShareName | |
| Default = [bool]$_.Default | |
| Local = [bool]$_.Local | |
| ServerName = $_.ServerName | |
| SystemName = $_.SystemName | |
| PrinterStatus = $_.PrinterStatus | |
| WorkOffline = [bool]$_.WorkOffline | |
| ConnectionPath = $connectionPath | |
| IsSharedQueue = $isSharedConnection | |
| IsTcpIpCandidate = ($_.PortName -match '^\d{1,3}(\.\d{1,3}){3}$') | |
| TcpIpAddressCandidate = if ($_.PortName -match '^\d{1,3}(\.\d{1,3}){3}$') { $_.PortName } else { $null } | |
| } | |
| } | |
| } | |
| catch {} | |
| $printers | Sort-Object Default -Descending, Name | |
| } | |
| function Get-InstalledPrinterDrivers { | |
| if (-not $IncludeDriverExportManifest) { return @() } | |
| try { | |
| Get-CimInstance Win32_PrinterDriver -ErrorAction Stop | ForEach-Object { | |
| [pscustomobject]@{ | |
| Name = $_.Name | |
| DriverPath = $_.DriverPath | |
| InfName = $_.InfName | |
| ConfigFile = $_.ConfigFile | |
| DataFile = $_.DataFile | |
| Environment = $_.SupportedPlatform | |
| Version = $_.Version | |
| } | |
| } | |
| } | |
| catch { | |
| @() | |
| } | |
| } | |
| function Correlate-Syncs { | |
| param( | |
| [object[]]$Accounts, | |
| [object[]]$Providers, | |
| [object[]]$ScopeCache | |
| ) | |
| foreach ($provider in $Providers) { | |
| $accountMatch = $Accounts | Where-Object { | |
| ($provider.TenantID -and $_.TenantID -and $provider.TenantID -eq $_.TenantID) -or | |
| ($provider.UserEmail -and $_.UserEmail -and $provider.UserEmail -eq $_.UserEmail) -or | |
| ($provider.UrlNamespace -and $_.UrlNamespace -and $provider.UrlNamespace -eq $_.UrlNamespace) | |
| } | Select-Object -First 1 | |
| $scopeMatches = @($ScopeCache | Where-Object |
This file contains hidden or 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
| #requires -Version 5.1 | |
| [CmdletBinding(SupportsShouldProcess = $true)] | |
| param( | |
| [Parameter(Mandatory)] | |
| [string]$InputPath, | |
| [switch]$RestoreMappedDrives = $true, | |
| [switch]$RestorePrinters = $true, | |
| [switch]$AttemptSharePointSync = $true, | |
| [switch]$SkipExisting = $true, | |
| [switch]$OpenSharePointUrlsIfSyncFails, | |
| [switch]$WhatIf | |
| ) | |
| Set-StrictMode -Version Latest | |
| $ErrorActionPreference = 'Continue' | |
| function Read-WorkspaceState { | |
| param([Parameter(Mandatory)][string]$Path) | |
| if (-not (Test-Path -LiteralPath $Path)) { | |
| throw "Input file not found: $Path" | |
| } | |
| Get-Content -LiteralPath $Path -Raw | ConvertFrom-Json | |
| } | |
| function Test-DriveExists { | |
| param([Parameter(Mandatory)][string]$DriveLetter) | |
| try { | |
| [bool](Get-PSDrive -Name $DriveLetter.TrimEnd(':') -ErrorAction Stop) | |
| } | |
| catch { | |
| $false | |
| } | |
| } | |
| function Restore-MappedDrive { | |
| param( | |
| [Parameter(Mandatory)]$Drive | |
| ) | |
| if (-not $Drive.DriveLetter -or -not $Drive.RemotePath) { | |
| Write-Warning "Skipping incomplete drive entry: $($Drive | ConvertTo-Json -Compress)" | |
| return | |
| } | |
| $driveLetter = [string]$Drive.DriveLetter | |
| $remotePath = [string]$Drive.RemotePath | |
| if ($SkipExisting -and (Test-DriveExists -DriveLetter $driveLetter)) { | |
| Write-Host "Drive already exists, skipping: $driveLetter" -ForegroundColor DarkYellow | |
| return | |
| } | |
| if ($PSCmdlet.ShouldProcess("$driveLetter -> $remotePath", "Map network drive")) { | |
| try { | |
| New-PSDrive -Name $driveLetter.TrimEnd(':') ` | |
| -PSProvider FileSystem ` | |
| -Root $remotePath ` | |
| -Persist ` | |
| -Scope Global ` | |
| -ErrorAction Stop | Out-Null | |
| Write-Host "Mapped $driveLetter to $remotePath" -ForegroundColor Green | |
| } | |
| catch { | |
| Write-Warning "Failed to map $driveLetter to $remotePath. $($_.Exception.Message)" | |
| } | |
| } | |
| } | |
| function Get-ExistingPrinters { | |
| try { @(Get-Printer -ErrorAction Stop) } catch { @() } | |
| } | |
| function Get-ExistingPrinterPorts { | |
| try { @(Get-PrinterPort -ErrorAction Stop) } catch { @() } | |
| } | |
| function Restore-SharedPrinter { | |
| param( | |
| [Parameter(Mandatory)]$Printer | |
| ) | |
| if (-not $Printer.ConnectionPath) { | |
| Write-Warning "Shared printer missing connection path: $($Printer.Name)" | |
| return | |
| } | |
| $existing = Get-ExistingPrinters | Where-Object { | |
| $_.Name -eq $Printer.Name -or $_.Name -eq $Printer.ConnectionPath | |
| } | |
| if ($SkipExisting -and $existing) { | |
| Write-Host "Printer already exists, skipping: $($Printer.Name)" -ForegroundColor DarkYellow | |
| return | |
| } | |
| if ($PSCmdlet.ShouldProcess($Printer.ConnectionPath, "Add shared printer connection")) { | |
| try { | |
| Add-Printer -ConnectionName $Printer.ConnectionPath -ErrorAction Stop | |
| Write-Host "Added shared printer: $($Printer.ConnectionPath)" -ForegroundColor Green | |
| } | |
| catch { | |
| Write-Warning "Failed to add shared printer $($Printer.ConnectionPath). $($_.Exception.Message)" | |
| } | |
| } | |
| } | |
| function Restore-TcpPrinter { | |
| param( | |
| [Parameter(Mandatory)]$Printer | |
| ) | |
| $printerName = [string]$Printer.Name | |
| $driverName = [string]$Printer.DriverName | |
| $portName = [string]$Printer.PortName | |
| $ipAddress = [string]$Printer.TcpIpAddressCandidate | |
| if (-not $printerName -or -not $driverName) { | |
| Write-Warning "Skipping incomplete TCP printer entry." | |
| return | |
| } | |
| $existingPrinter = Get-ExistingPrinters | Where-Object { $_.Name -eq $printerName } | |
| if ($SkipExisting -and $existingPrinter) { | |
| Write-Host "Printer already exists, skipping: $printerName" -ForegroundColor DarkYellow | |
| return | |
| } | |
| if (-not $ipAddress -and $portName -match '^\d{1,3}(\.\d{1,3}){3}$') { | |
| $ipAddress = $portName | |
| } | |
| if (-not $ipAddress) { | |
| Write-Warning "No IP candidate found for printer '$printerName'. Cannot safely rebuild." | |
| return | |
| } | |
| $existingPort = Get-ExistingPrinterPorts | Where-Object { $_.Name -eq $portName -or $_.Name -eq $ipAddress } | |
| $chosenPortName = if ($portName) { $portName } else { $ipAddress } | |
| if (-not $existingPort) { | |
| if ($PSCmdlet.ShouldProcess($chosenPortName, "Create TCP printer port")) { | |
| try { | |
| Add-PrinterPort -Name $chosenPortName -PrinterHostAddress $ipAddress -ErrorAction Stop | |
| Write-Host "Created printer port: $chosenPortName ($ipAddress)" -ForegroundColor Green | |
| } | |
| catch { | |
| Write-Warning "Failed creating port '$chosenPortName'. $($_.Exception.Message)" | |
| return | |
| } | |
| } | |
| } | |
| if ($PSCmdlet.ShouldProcess($printerName, "Create TCP printer")) { | |
| try { | |
| Add-Printer -Name $printerName -DriverName $driverName -PortName $chosenPortName -ErrorAction Stop | |
| Write-Host "Added TCP printer: $printerName" -ForegroundColor Green | |
| } | |
| catch { | |
| Write-Warning "Failed adding TCP printer '$printerName'. Driver '$driverName' may be missing. $($_.Exception.Message)" | |
| } | |
| } | |
| } | |
| function Set-DefaultPrinterSafe { | |
| param( | |
| [Parameter(Mandatory)][string]$PrinterName | |
| ) | |
| if ($PSCmdlet.ShouldProcess($PrinterName, "Set default printer")) { | |
| try { | |
| $null = Invoke-CimMethod -ClassName Win32_Printer -MethodName SetDefaultPrinter -Arguments @{} -Filter "Name='$($PrinterName.Replace("'","''"))'" -ErrorAction Stop | |
| Write-Host "Set default printer: $PrinterName" -ForegroundColor Green | |
| } | |
| catch { | |
| try { | |
| $printer = Get-CimInstance Win32_Printer -Filter "Name='$($PrinterName.Replace("'","''"))'" -ErrorAction Stop | |
| $null = Invoke-CimMethod -InputObject $printer -MethodName SetDefaultPrinter -Arguments @{} -ErrorAction Stop | |
| Write-Host "Set default printer: $PrinterName" -ForegroundColor Green | |
| } | |
| catch { | |
| Write-Warning "Failed to set default printer '$PrinterName'. $($_.Exception.Message)" | |
| } | |
| } | |
| } | |
| } | |
| function Test-OneDriveRunning { | |
| Get-Process -Name OneDrive -ErrorAction SilentlyContinue | Select-Object -First 1 | |
| } | |
| function Start-SharePointSyncAttempt { | |
| param( | |
| [Parameter(Mandatory)]$Sync | |
| ) | |
| $targetName = if ($Sync.DisplayName) { $Sync.DisplayName } else { $Sync.SiteURL } | |
| if ($Sync.SyncUrl) { | |
| if ($PSCmdlet.ShouldProcess($targetName, "Attempt SharePoint/OneDrive sync")) { | |
| try { | |
| Start-Process -FilePath $Sync.SyncUrl -ErrorAction Stop | Out-Null | |
| Write-Host "Launched sync URL for: $targetName" -ForegroundColor Green | |
| return | |
| } | |
| catch { | |
| Write-Warning "Failed launching sync URL for '$targetName'. $($_.Exception.Message)" | |
| } | |
| } | |
| } | |
| if ($OpenSharePointUrlsIfSyncFails) { | |
| $fallbackUrl = if ($Sync.LibraryURL) { $Sync.LibraryURL } elseif ($Sync.WebURL) { $Sync.WebURL } else { $Sync.SiteURL } | |
| if ($fallbackUrl -and $PSCmdlet.ShouldProcess($fallbackUrl, "Open fallback URL")) { | |
| try { | |
| Start-Process -FilePath $fallbackUrl -ErrorAction Stop | Out-Null | |
| Write-Host "Opened fallback URL for: $targetName" -ForegroundColor Yellow | |
| } | |
| catch { | |
| Write-Warning "Failed opening fallback URL '$fallbackUrl'. $($_.Exception.Message)" | |
| } | |
| } | |
| } | |
| } | |
| $state = Read-WorkspaceState -Path $InputPath | |
| Write-Host "Loaded workspace state from $InputPath" -ForegroundColor Cyan | |
| Write-Host "Captured from $($state.ComputerName)\$($state.UserName) at $($state.CapturedAt)" -ForegroundColor Cyan | |
| Write-Host "" | |
| if ($RestoreMappedDrives -and $state.MappedDrives) { | |
| Write-Host "Restoring mapped drives..." -ForegroundColor Yellow | |
| foreach ($drive in $state.MappedDrives) { | |
| Restore-MappedDrive -Drive $drive | |
| } | |
| Write-Host "" | |
| } | |
| if ($RestorePrinters -and $state.Printers) { | |
| Write-Host "Restoring printers..." -ForegroundColor Yellow | |
| $sharedPrinters = @($state.Printers | Where-Object { $_.IsSharedQueue -and $_.ConnectionPath }) | |
| $tcpPrinters = @($state.Printers | Where-Object { $_.IsTcpIpCandidate -and -not $_.IsSharedQueue }) | |
| foreach ($printer in $sharedPrinters) { | |
| Restore-SharedPrinter -Printer $printer | |
| } | |
| foreach ($printer in $tcpPrinters) { | |
| Restore-TcpPrinter -Printer $printer | |
| } | |
| $defaultPrinter = @($state.Printers | Where-Object { $_.Default } | Select-Object -First 1) | |
| if ($defaultPrinter) { | |
| Set-DefaultPrinterSafe -PrinterName $defaultPrinter.Name | |
| } | |
| Write-Host "" | |
| } | |
| if ($AttemptSharePointSync -and $state.CorrelatedSyncs) { | |
| Write-Host "Attempting SharePoint/OneDrive sync restoration..." -ForegroundColor Yellow | |
| if (-not (Test-OneDriveRunning)) { | |
| Write-Warning "OneDrive is not currently running. SharePoint sync attempts may fail until the user signs into OneDrive." | |
| } | |
| foreach ($sync in $state.CorrelatedSyncs | Where-Object { $_.SyncType -eq 'SharePoint' -or $_.SyncType -eq 'OneDrive' }) { | |
| Start-SharePointSyncAttempt -Sync $sync | |
| } | |
| Write-Host "" | |
| } | |
| Write-Host "Restore routine complete." -ForegroundColor Green |
Calvindd2f
commented
Apr 1, 2026
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment