EnhancedDeviceMigrationAO.psm1
#Region '.\Public\Add-LocalUser.ps1' -1 function Add-LocalUser { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$TempUser, [Parameter(Mandatory = $true)] [string]$TempUserPassword, [Parameter(Mandatory = $true)] [string]$Description, [Parameter(Mandatory = $true)] [string]$Group ) Begin { Write-EnhancedLog -Message "Starting Add-LocalUser function" -Level "INFO" Log-Params -Params @{ TempUser = $TempUser TempUserPassword = $TempUserPassword Description = $Description Group = $Group } } Process { try { Write-EnhancedLog -Message "Creating Local User Account" -Level "INFO" $Password = ConvertTo-SecureString -AsPlainText $TempUserPassword -Force New-LocalUser -Name $TempUser -Password $Password -Description $Description -AccountNeverExpires Add-LocalGroupMember -Group $Group -Member $TempUser } catch { Write-EnhancedLog -Message "An error occurred while adding local user: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting Add-LocalUser function" -Level "INFO" } } # # Define parameters # $AddLocalUserParams = @{ # TempUser = "YourTempUser" # TempUserPassword = "YourTempUserPassword" # Description = "account for autologin" # Group = "Administrators" # } # # Example usage with splatting # Add-LocalUser @AddLocalUserParams #EndRegion '.\Public\Add-LocalUser.ps1' 54 #Region '.\Public\Backup-DownloadsToOneDrive.ps1' -1 function Backup-DownloadsToOneDrive { [CmdletBinding()] param () Begin { Write-EnhancedLog -Message "Starting Backup-DownloadsToOneDrive function" -Level "INFO" } Process { try { # Define full-name variables and check for OneDrive directory existence $oneDriveDirectory = (Get-ChildItem -Path "$env:USERPROFILE" -Filter "OneDrive - *" -Directory).FullName # Exit with an error if the OneDrive directory does not exist if (-not $oneDriveDirectory) { Throw "OneDrive directory not found. Please ensure OneDrive is set up correctly." } $downloadsPath = "$env:USERPROFILE\Downloads" $backupPath = Join-Path -Path $oneDriveDirectory -ChildPath "DownloadsBackup" # Use splatting for function parameters $params = @{ SourcePath = $downloadsPath + "\" DestinationPath = $backupPath } # Execute the function with splatting Copy-ItemsWithRobocopy @params Write-EnhancedLog -Message "Backup of Downloads to OneDrive completed successfully." -Level "INFO" } catch { Write-EnhancedLog -Message "An error occurred in Backup-DownloadsToOneDrive function: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting Backup-DownloadsToOneDrive function" -Level "INFO" } } # Example usage # Backup-DownloadsToOneDrive #EndRegion '.\Public\Backup-DownloadsToOneDrive.ps1' 46 #Region '.\Public\Check-OneDriveBackupStatus.ps1' -1 function Check-OneDriveBackupStatus { [CmdletBinding()] param () Begin { Write-EnhancedLog -Message "Starting Check-OneDriveBackupStatus function" -Level "INFO" } Process { try { # Attempt to find the OneDrive directory $oneDriveDirectory = (Get-ChildItem "$env:USERPROFILE" -Filter "OneDrive - *" -Directory).FullName # Check if the OneDrive directory exists if (-not $oneDriveDirectory) { Write-EnhancedLog -Message "OneDrive directory does not exist. Remediation is not possible for now." -Level "WARNING" exit 0 } # Define the backup path within the OneDrive directory $backupPath = Join-Path $oneDriveDirectory "DownloadsBackup" # Check if the DownloadsBackup folder exists and contains files if (Test-Path $backupPath) { $fileCount = (Get-ChildItem -Path $backupPath -Recurse -File).Count if ($fileCount -gt 0) { Write-EnhancedLog -Message "DownloadsBackup folder detected with files at $backupPath. Remediation needed." -Level "WARNING" exit 1 } else { Write-EnhancedLog -Message "DownloadsBackup folder exists at $backupPath but is empty. Remediation needed." -Level "WARNING" exit 1 } } else { Write-EnhancedLog -Message "DownloadsBackup folder does not exist at $backupPath. Remediation needed." -Level "WARNING" exit 1 } } catch { Write-EnhancedLog -Message "An error occurred in Check-OneDriveBackupStatus function: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting Check-OneDriveBackupStatus function" -Level "INFO" } } # Example usage # Check-OneDriveBackupStatus #EndRegion '.\Public\Check-OneDriveBackupStatus.ps1' 51 #Region '.\Public\Check-OneDriveSyncStatus.ps1' -1 function Check-OneDriveSyncStatus { [CmdletBinding()] param ( [string]$OneDriveLibPath ) Begin { Write-EnhancedLog -Message "Starting Check-OneDriveSyncStatus function" -Level "INFO" Log-Params -Params @{ OneDriveLibPath = $OneDriveLibPath } # Check if running elevated $isElevated = (New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) if ($isElevated) { Write-EnhancedLog -Message "Session is running elevated. Skipping Check-OneDriveSyncStatus function." -Level "INFO" return } # Import OneDriveLib.dll to check current OneDrive Sync Status Import-Module $OneDriveLibPath } Process { if ($isElevated) { return } try { $Status = Get-ODStatus if (-not $Status) { Write-EnhancedLog -Message "OneDrive is not running or the user is not logged in to OneDrive." -Level "WARNING" return } # Create objects with known statuses listed. $Success = @( "Shared", "UpToDate", "Up To Date" ) $InProgress = @( "SharedSync", "Shared Sync", "Syncing" ) $Failed = @( "Error", "ReadOnly", "Read Only", "OnDemandOrUnknown", "On Demand or Unknown", "Paused") # Multiple OD4B accounts may be found. Consider adding logic to identify correct OD4B. Iterate through all accounts to check status and log the result. ForEach ($s in $Status) { $StatusString = $s.StatusString $DisplayName = $s.DisplayName $User = $s.UserName if ($s.StatusString -in $Success) { Write-EnhancedLog -Message "OneDrive sync status is healthy: Display Name: $DisplayName, User: $User, Status: $StatusString" -Level "INFO" } elseif ($s.StatusString -in $InProgress) { Write-EnhancedLog -Message "OneDrive sync status is currently syncing: Display Name: $DisplayName, User: $User, Status: $StatusString" -Level "INFO" } elseif ($s.StatusString -in $Failed) { Write-EnhancedLog -Message "OneDrive sync status is in a known error state: Display Name: $DisplayName, User: $User, Status: $StatusString" -Level "ERROR" } elseif (-not $s.StatusString) { Write-EnhancedLog -Message "Unable to get OneDrive Sync Status for Display Name: $DisplayName, User: $User" -Level "WARNING" } if (-not $Status.StatusString) { Write-EnhancedLog -Message "Unable to get OneDrive Sync Status." -Level "ERROR" } } } catch { Write-EnhancedLog -Message "An error occurred while checking OneDrive sync status: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting Check-OneDriveSyncStatus function" -Level "INFO" } } # Example usage # Check-OneDriveSyncStatus -OneDriveLibPath "C:\ProgramData\AADMigration\Files\OneDriveLib.dll" #EndRegion '.\Public\Check-OneDriveSyncStatus.ps1' 78 #Region '.\Public\Create-EventLogSource.ps1' -1 function Create-EventLogSource { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$LogName, [Parameter(Mandatory = $true)] [string]$Source ) Begin { Write-EnhancedLog -Message "Starting Create-EventLogSource function" -Level "INFO" Log-Params -Params @{ LogName = $LogName Source = $Source } } Process { try { if (-not (Get-EventLog -LogName $LogName -Source $Source -ErrorAction SilentlyContinue)) { New-EventLog -LogName $LogName -Source $Source -ErrorAction Stop } } catch { Write-EnhancedLog -Message "An error occurred while creating the event log source: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting Create-EventLogSource function" -Level "INFO" } } # $CreateEventLogSourceParams = @{ # LogName = "Application" # Source = "AAD_Migration_Script" # } # Create-EventLogSource @CreateEventLogSourceParams #EndRegion '.\Public\Create-EventLogSource.ps1' 41 #Region '.\Public\Create-OneDriveRemediationTask.ps1' -1 function Create-OneDriveRemediationTask { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$OneDriveExePath, [Parameter(Mandatory = $true)] [string]$ScheduledTaskName, [Parameter(Mandatory = $true)] [string]$ScheduledTaskDescription, [Parameter(Mandatory = $false)] [string]$ScheduledTaskArgumentList ) Begin { Write-EnhancedLog -Message "Starting Create-OneDriveRemediationTask function" -Level "INFO" Log-Params -Params @{ OneDriveExePath = $OneDriveExePath ScheduledTaskName = $ScheduledTaskName ScheduledTaskDescription = $ScheduledTaskDescription ScheduledTaskArgumentList = $ScheduledTaskArgumentList } } Process { try { # $userId = (Get-WmiObject -Class Win32_ComputerSystem).UserName $userId = $env:UserName if (-not $userId) { throw "Unable to retrieve the current user ID." } Write-EnhancedLog -Message "User ID retrieved: $userId" -Level "INFO" $actionParams = @{ Execute = $OneDriveExePath } if ($ScheduledTaskArgumentList) { $actionParams.Argument = $ScheduledTaskArgumentList } $action = New-ScheduledTaskAction @actionParams $trigger = New-ScheduledTaskTrigger -AtLogOn $principalParams = @{ UserId = $userId } $principal = New-ScheduledTaskPrincipal @principalParams $taskParams = @{ Action = $action Trigger = $trigger Principal = $principal TaskName = $ScheduledTaskName Description = $ScheduledTaskDescription Force = $true } $task = Register-ScheduledTask @taskParams Start-ScheduledTask -TaskName $ScheduledTaskName # $DBG Start-Sleep -Seconds 5 Unregister-ScheduledTask -TaskName $ScheduledTaskName -Confirm:$false } catch { Write-EnhancedLog -Message "An error occurred in Create-OneDriveRemediationTask function: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting Create-OneDriveRemediationTask function" -Level "INFO" } } # $CreateOneDriveRemediationTaskParams = @{ # OneDriveExePath = "C:\Program Files\Microsoft OneDrive\OneDrive.exe" # ScheduledTaskName = "OneDriveRemediation" # ScheduledTaskDescription = "Restart OneDrive to kick off KFM sync" # ScheduledTaskArgumentList = "" # } # Create-OneDriveRemediationTask @CreateOneDriveRemediationTaskParams #EndRegion '.\Public\Create-OneDriveRemediationTask.ps1' 87 #Region '.\Public\Create-OneDriveSyncStatusTask.ps1' -1 function Create-OneDriveSyncStatusTask { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$TaskPath, [Parameter(Mandatory = $true)] [string]$TaskName, [Parameter(Mandatory = $true)] [string]$ScriptDirectory, [Parameter(Mandatory = $true)] [string]$ScriptName, [Parameter(Mandatory = $true)] [string]$TaskArguments, [Parameter(Mandatory = $true)] [string]$TaskRepetitionDuration, [Parameter(Mandatory = $true)] [string]$TaskRepetitionInterval, [Parameter(Mandatory = $true)] [string]$TaskPrincipalGroupId, [Parameter(Mandatory = $true)] [string]$PowerShellPath, [Parameter(Mandatory = $true)] [string]$TaskDescription ) Begin { Write-EnhancedLog -Message "Starting Create-OneDriveSyncStatusTask function" -Level "INFO" Log-Params -Params @{ TaskPath = $TaskPath TaskName = $TaskName ScriptDirectory = $ScriptDirectory ScriptName = $ScriptName TaskArguments = $TaskArguments TaskRepetitionDuration = $TaskRepetitionDuration TaskRepetitionInterval = $TaskRepetitionInterval TaskPrincipalGroupId = $TaskPrincipalGroupId PowerShellPath = $PowerShellPath TaskDescription = $TaskDescription } } Process { try { $arguments = $TaskArguments.Replace("{ScriptPath}", "$ScriptDirectory\$ScriptName") $actionParams = @{ Execute = $PowerShellPath Argument = $arguments } $action = New-ScheduledTaskAction @actionParams $triggerParams = @{ AtLogOn = $true } $trigger = New-ScheduledTaskTrigger @triggerParams $principalParams = @{ GroupId = $TaskPrincipalGroupId } $principal = New-ScheduledTaskPrincipal @principalParams $registerTaskParams = @{ Principal = $principal Action = $action Trigger = $trigger TaskName = $TaskName Description = $TaskDescription TaskPath = $TaskPath } $Task = Register-ScheduledTask @registerTaskParams $Task.Triggers.Repetition.Duration = $TaskRepetitionDuration $Task.Triggers.Repetition.Interval = $TaskRepetitionInterval $Task | Set-ScheduledTask } catch { Write-EnhancedLog -Message "An error occurred while creating the OneDrive sync status task: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting Create-OneDriveSyncStatusTask function" -Level "INFO" } } # # Example usage with splatting # $CreateOneDriveSyncStatusTaskParams = @{ # TaskPath = "AAD Migration" # TaskName = "AADM Get OneDrive Sync Status" # ScriptDirectory = "C:\ProgramData\AADMigration\Scripts" # ScriptName = "Check-OneDriveSyncStatus.ps1" # TaskArguments = "-NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -file `"{ScriptPath}`"" # TaskRepetitionDuration = "P1D" # TaskRepetitionInterval = "PT30M" # TaskPrincipalGroupId = "BUILTIN\Users" # PowerShellPath = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" # TaskDescription = "Get current OneDrive Sync Status and write to event log" # } # Create-OneDriveSyncStatusTask @CreateOneDriveSyncStatusTaskParams #EndRegion '.\Public\Create-OneDriveSyncStatusTask.ps1' 102 #Region '.\Public\Create-PPKG.ps1' -1 function Create-PPKG { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$ICDPath, [Parameter(Mandatory = $true)] [string]$CustomizationXMLPath, [Parameter(Mandatory = $true)] [string]$PackagePath, [Parameter(Mandatory = $false)] [string]$ProductName, [Parameter(Mandatory = $false)] [string]$StoreFile, [Parameter(Mandatory = $false)] [string]$MSPackageRoot, [Parameter(Mandatory = $false)] [string]$OEMInputXML, [Parameter(Mandatory = $false)] [hashtable]$Variables, [Parameter(Mandatory = $false)] [bool]$Encrypted = $false, [Parameter(Mandatory = $false)] [bool]$Overwrite = $true ) Begin { Write-EnhancedLog -Message "Starting Create-PPKG function" -Level "INFO" Log-Params -Params @{ ICDPath = $ICDPath CustomizationXMLPath = $CustomizationXMLPath PackagePath = $PackagePath ProductName = $ProductName StoreFile = $StoreFile MSPackageRoot = $MSPackageRoot OEMInputXML = $OEMInputXML Variables = $Variables Encrypted = $Encrypted Overwrite = $Overwrite } # Ensure ICD.exe exists if (-not (Test-Path -Path $ICDPath)) { throw "ICD.exe not found at: $ICDPath" } # Ensure Customization XML file exists if (-not (Test-Path -Path $CustomizationXMLPath)) { throw "Customization XML file not found at: $CustomizationXMLPath" } } Process { try { # Build the command line arguments using a list $ICD_args = [System.Collections.Generic.List[string]]::new() $ICD_args.Add("/Build-ProvisioningPackage") $ICD_args.Add("/CustomizationXML:`"$CustomizationXMLPath`"") $ICD_args.Add("/PackagePath:`"$PackagePath`"") if ($Encrypted) { $ICD_args.Add("+Encrypted") } else { $ICD_args.Add("-Encrypted") } if ($Overwrite) { $ICD_args.Add("+Overwrite") } else { $ICD_args.Add("-Overwrite") } if ($ProductName) { $ICD_args.Add("/ProductName:`"$ProductName`"") } if ($StoreFile) { $ICD_args.Add("/StoreFile:`"$StoreFile`"") } if ($MSPackageRoot) { $ICD_args.Add("/MSPackageRoot:`"$MSPackageRoot`"") } if ($OEMInputXML) { $ICD_args.Add("/OEMInputXML:`"$OEMInputXML`"") } if ($Variables) { foreach ($key in $Variables.Keys) { $ICD_args.Add("/Variables:`"$key=$($Variables[$key])`"") } } $ICD_args_string = $ICD_args -join " " Write-EnhancedLog -Message "Running ICD.exe with arguments: $ICD_args_string" -Level "INFO" Start-Process -FilePath $ICDPath -ArgumentList $ICD_args_string -Wait -NoNewWindow } catch { Write-EnhancedLog -Message "An error occurred while processing the Create-PPKG function: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting Create-PPKG function" -Level "INFO" } } # Example usage # $ppkgParams = @{ # ICDPath = "C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Imaging and Configuration Designer\x86\ICD.exe" # CustomizationXMLPath = "C:\code\CB\Entra\DeviceMigration\Files\customizations.xml" # PackagePath = "C:\code\CB\Entra\DeviceMigration\Files\ProvisioningPackage.ppkg" # Encrypted = $false # Overwrite = $true # } # Create-PPKG @ppkgParams #EndRegion '.\Public\Create-PPKG.ps1' 128 #Region '.\Public\Create-ProvPackageAADEnrollment-Archive.ps1' -1 # function Create-ProvPackageAADEnrollment { # [CmdletBinding()] # param ( # [Parameter(Mandatory = $true)] # [string]$Source, # [Parameter(Mandatory = $true)] # [string]$Destination # ) # Begin { # Write-EnhancedLog -Message "Starting Create-ProvPackage-AADEnrollment function" -Level "INFO" # Log-Params -Params @{ # Source = $Source # Destination = $Destination # } # } # Process { # try { # # Create a provisioning package for AAD bulk enrollment (placeholder as the actual creation depends on your environment) # # Assuming you have a script or method to create it # # Copy the provisioning package to the Files folder # Copy-Item -Path $Source -Destination $Destination -Force # } catch { # Write-EnhancedLog -Message "An error occurred while processing the Create-ProvPackage-AADEnrollment function: $($_.Exception.Message)" -Level "ERROR" # Handle-Error -ErrorRecord $_ # } # } # End { # Write-EnhancedLog -Message "Exiting Create-ProvPackage-AADEnrollment function" -Level "INFO" # } # } # # Example usage # # Create-ProvPackageAADEnrollment -Source 'C:\Path\To\Your\ProvisioningPackage.ppkg' -Destination 'C:\YourPath\Files\ProvisioningPackage.ppkg' #EndRegion '.\Public\Create-ProvPackageAADEnrollment-Archive.ps1' 38 #Region '.\Public\Disable-OOBEPrivacy.ps1' -1 function Disable-OOBEPrivacy { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$OOBERegistryPath, [Parameter(Mandatory = $true)] [string]$OOBEName, [Parameter(Mandatory = $true)] [string]$OOBEValue, [Parameter(Mandatory = $true)] [string]$AnimationRegistryPath, [Parameter(Mandatory = $true)] [string]$AnimationName, [Parameter(Mandatory = $true)] [string]$AnimationValue, [Parameter(Mandatory = $true)] [string]$LockRegistryPath, [Parameter(Mandatory = $true)] [string]$LockName, [Parameter(Mandatory = $true)] [string]$LockValue ) Begin { Write-EnhancedLog -Message "Starting Disable-OOBEPrivacy function" -Level "INFO" Log-Params -Params @{ OOBERegistryPath = $OOBERegistryPath OOBEName = $OOBEName OOBEValue = $OOBEValue AnimationRegistryPath = $AnimationRegistryPath AnimationName = $AnimationName AnimationValue = $AnimationValue LockRegistryPath = $LockRegistryPath LockName = $LockName LockValue = $LockValue } } Process { try { Write-EnhancedLog -Message "Disabling privacy experience" -Level "INFO" if (-not (Test-Path -Path $OOBERegistryPath)) { New-Item -Path $OOBERegistryPath -Force | Out-Null } New-ItemProperty -Path $OOBERegistryPath -Name $OOBEName -Value $OOBEValue -PropertyType DWORD -Force -Verbose Write-EnhancedLog -Message "Disabling first logon animation" -Level "INFO" if (-not (Test-Path -Path $AnimationRegistryPath)) { New-Item -Path $AnimationRegistryPath -Force | Out-Null } New-ItemProperty -Path $AnimationRegistryPath -Name $AnimationName -Value $AnimationValue -PropertyType DWORD -Force -Verbose Write-EnhancedLog -Message "Removing lock screen" -Level "INFO" if (-not (Test-Path -Path $LockRegistryPath)) { New-Item -Path $LockRegistryPath -Force | Out-Null } New-ItemProperty -Path $LockRegistryPath -Name $LockName -Value $LockValue -PropertyType DWORD -Force -Verbose } catch { Write-EnhancedLog -Message "An error occurred while disabling OOBE privacy: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting Disable-OOBEPrivacy function" -Level "INFO" } } # # Example usage with splatting # $DisableOOBEPrivacyParams = @{ # OOBERegistryPath = 'HKLM:\Software\Policies\Microsoft\Windows\OOBE' # OOBEName = 'DisablePrivacyExperience' # OOBEValue = '1' # AnimationRegistryPath = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon' # AnimationName = 'EnableFirstLogonAnimation' # AnimationValue = '0' # LockRegistryPath = 'HKLM:\Software\Policies\Microsoft\Windows\Personalization' # LockName = 'NoLockScreen' # LockValue = '1' # } # Disable-OOBEPrivacy @DisableOOBEPrivacyParams #EndRegion '.\Public\Disable-OOBEPrivacy.ps1' 91 #Region '.\Public\Download-ADKOffline.ps1' -1 function Download-ADKOffline { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$ADKUrl = "https://go.microsoft.com/fwlink/?linkid=2271337", [Parameter(Mandatory = $true)] [string]$DownloadPath = "$env:TEMP\adksetup.exe", [Parameter(Mandatory = $true)] [string]$OfflinePath = "$env:TEMP\ADKOffline" ) Begin { Write-EnhancedLog -Message "Starting Download-ADKOffline function" -Level "INFO" Log-Params -Params @{ ADKUrl = $ADKUrl DownloadPath = $DownloadPath OfflinePath = $OfflinePath } } Process { try { # Download the ADK setup file Write-EnhancedLog -Message "Downloading ADK from: $ADKUrl to: $DownloadPath" -Level "INFO" Invoke-WebRequest -Uri $ADKUrl -OutFile $DownloadPath # Create offline path if it does not exist if (-not (Test-Path -Path $OfflinePath)) { New-Item -ItemType Directory -Path $OfflinePath -Force } # Download the ADK components for offline installation Write-EnhancedLog -Message "Downloading ADK components for offline installation to: $OfflinePath" -Level "INFO" Start-Process -FilePath $DownloadPath -ArgumentList "/quiet", "/layout $OfflinePath" -Wait -NoNewWindow } catch { Write-EnhancedLog -Message "An error occurred while processing the Download-ADKOffline function: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting Download-ADKOffline function" -Level "INFO" } } # Example usage # $adkParams = @{ # ADKUrl = 'https://go.microsoft.com/fwlink/?linkid=2271337' # DownloadPath = "$env:TEMP\adksetup.exe" # OfflinePath = "$env:TEMP\ADKOffline" # } # Download-ADKOffline @adkParams #EndRegion '.\Public\Download-ADKOffline.ps1' 56 #Region '.\Public\Download-InstallMDT.ps1' -1 # function Download-InstallMDT { # [CmdletBinding()] # param ( # [Parameter(Mandatory = $true)] # [string]$Url, # [Parameter(Mandatory = $true)] # [string]$Destination, # [Parameter(Mandatory = $true)] # [string]$FilesFolder # ) # Begin { # Write-EnhancedLog -Message "Starting Download-Install-MDT function" -Level "INFO" # Log-Params -Params @{ # Url = $Url # Destination = $Destination # FilesFolder = $FilesFolder # } # } # Process { # try { # # Download and install Microsoft Deployment Toolkit # Invoke-WebRequest -Uri $Url -OutFile $Destination # Start-Process -FilePath $Destination -ArgumentList "/quiet" -Wait # # Copy ServiceUI.exe to Files folder # Copy-Item -Path "C:\Program Files\Microsoft Deployment Toolkit\Templates\Distribution\Tools\x64\ServiceUI.exe" -Destination $FilesFolder # } catch { # Write-EnhancedLog -Message "An error occurred while processing the Download-InstallMDT function: $($_.Exception.Message)" -Level "ERROR" # Handle-Error -ErrorRecord $_ # } # } # End { # Write-EnhancedLog -Message "Exiting Download-Install-MDT function" -Level "INFO" # } # } # # Example usage # # Download-InstallMDT -Url 'https://download.microsoft.com/download/9/e/1/9e1e94ec-5463-46b7-9f3c-b225034c3a70/MDT_KB4564442.exe' -Destination 'C:\YourPath\Files\MDT.exe' -FilesFolder 'C:\YourPath\Files' #EndRegion '.\Public\Download-InstallMDT.ps1' 44 #Region '.\Public\Download-MigrationTool.ps1' -1 function Download-MigrationTool { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$Url, [Parameter(Mandatory = $true)] [string]$Destination ) Begin { Write-EnhancedLog -Message "Starting Download-MigrationTool function" -Level "INFO" Log-Params -Params @{ Url = $Url Destination = $Destination } } Process { try { # Download Migration Tool Invoke-WebRequest -Uri $Url -OutFile $Destination } catch { Write-EnhancedLog -Message "An error occurred while processing the Download-MigrationTool function: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting Download-MigrationTool function" -Level "INFO" } } # Example usage # Download-MigrationTool -Url "https://example.com/tool.zip" -Destination "C:\path\to\destination" #EndRegion '.\Public\Download-MigrationTool.ps1' 36 #Region '.\Public\Download-OneDriveLib.ps1' -1 function Download-OneDriveLib { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$Destination ) Begin { Write-EnhancedLog -Message "Starting Download-OneDriveLib function" -Level "INFO" Log-Params -Params @{ Destination = $Destination } } Process { try { # Get the latest release info from GitHub $latestRelease = Invoke-RestMethod -Uri "https://api.github.com/repos/rodneyviana/ODSyncService/releases/latest" $url = $latestRelease.assets | Where-Object { $_.name -eq "OneDriveLib.dll" } | Select-Object -ExpandProperty browser_download_url if (-not $url) { throw "No matching file found for OneDriveLib.dll" } Write-EnhancedLog -Message "Downloading OneDriveLib.dll from: $url" -Level "INFO" # Download the file Invoke-WebRequest -Uri $url -OutFile $Destination } catch { Write-EnhancedLog -Message "An error occurred while processing the Download-OneDriveLib function: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting Download-OneDriveLib function" -Level "INFO" } } # Example usage # Download-OneDriveLib -Destination 'C:\YourPath\Files\OneDriveLib.dll' #EndRegion '.\Public\Download-OneDriveLib.ps1' 42 #Region '.\Public\Download-PSAppDeployToolkit-Archive.ps1' -1 # function Download-PSAppDeployToolkit { # [CmdletBinding()] # param ( # [Parameter(Mandatory = $true)] # [string]$Url, # [Parameter(Mandatory = $true)] # [string]$Destination, # [Parameter(Mandatory = $true)] # [string]$ToolkitFolder # ) # Begin { # Write-EnhancedLog -Message "Starting Download-PSAppDeployToolkit function" -Level "INFO" # Log-Params -Params @{ # Url = $Url # Destination = $Destination # ToolkitFolder = $ToolkitFolder # } # } # Process { # try { # # Download and extract PSAppDeployToolkit # Invoke-WebRequest -Uri $Url -OutFile $Destination # Expand-Archive -Path $Destination -DestinationPath $ToolkitFolder -Force # } catch { # Write-EnhancedLog -Message "An error occurred while processing the Download-PSAppDeployToolkit function: $($_.Exception.Message)" -Level "ERROR" # Handle-Error -ErrorRecord $_ # } # } # End { # Write-EnhancedLog -Message "Exiting Download-PSAppDeployToolkit function" -Level "INFO" # } # } # # Example usage # # Download-PSAppDeployToolkit -Url 'https://github.com/PSAppDeployToolkit/PSAppDeployToolkit/releases/download/v3.8.4/PSAppDeployToolkit_v3.8.4.zip' -Destination 'C:\YourPath\Files\PSAppDeployToolkit.zip' -ToolkitFolder 'C:\YourPath\Toolkit' #EndRegion '.\Public\Download-PSAppDeployToolkit-Archive.ps1' 41 #Region '.\Public\Execute-MigrationToolkit.ps1' -1 function Execute-MigrationToolkit { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$ServiceUI, [Parameter(Mandatory = $true)] [string]$ExePath ) Begin { Write-EnhancedLog -Message "Starting Execute-MigrationToolkit function" -Level "INFO" Log-Params -Params @{ ServiceUI = $ServiceUI ExePath = $ExePath } } Process { try { $targetProcesses = @(Get-WmiObject -Query "Select * FROM Win32_Process WHERE Name='explorer.exe'" -ErrorAction SilentlyContinue) if ($targetProcesses.Count -eq 0) { Write-EnhancedLog -Message "No user logged in, running without ServiceUI" -Level "INFO" Start-Process -FilePath $ExePath -ArgumentList '-DeployMode "NonInteractive"' -Wait -NoNewWindow } else { foreach ($targetProcess in $targetProcesses) { $Username = $targetProcess.GetOwner().User Write-EnhancedLog -Message "$Username logged in, running with ServiceUI" -Level "INFO" } Start-Process -FilePath $ServiceUI -ArgumentList "-Process:explorer.exe $ExePath" -NoNewWindow } } catch { $ErrorMessage = $_.Exception.Message Write-EnhancedLog -Message "An error occurred: $ErrorMessage" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Install Exit Code = $LASTEXITCODE" -Level "INFO" Write-EnhancedLog -Message "Exiting Execute-MigrationToolkit function" -Level "INFO" Exit $LASTEXITCODE } } # # Define paths # $ToolkitPaths = @{ # ServiceUI = "C:\ProgramData\AADMigration\Files\ServiceUI.exe" # ExePath = "C:\ProgramData\AADMigration\Toolkit\Deploy-Application.exe" # } # # Example usage with splatting # Execute-MigrationToolkit @ToolkitPaths #EndRegion '.\Public\Execute-MigrationToolkit.ps1' 54 #Region '.\Public\Install-ADKFromMSI.ps1' -1 function Install-ADKFromMSI { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$OfflinePath, [Parameter(Mandatory = $true)] [string]$ICDPath = "C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Imaging and Configuration Designer\x86\ICD.exe" ) Begin { Write-EnhancedLog -Message "Starting Install-ADKFromMSI function" -Level "INFO" Log-Params -Params @{ OfflinePath = $OfflinePath ICDPath = $ICDPath } # Ensure offline path exists if (-not (Test-Path -Path $OfflinePath)) { throw "Offline path not found: $OfflinePath" } } Process { try { # Get all MSI files in the offline path $MSIFiles = Get-ChildItem -Path $OfflinePath -Filter *.msi if (-not $MSIFiles) { throw "No MSI files found in: $OfflinePath" } # Install each MSI file foreach ($MSI in $MSIFiles) { Write-EnhancedLog -Message "Installing MSI: $($MSI.FullName)" -Level "INFO" Start-Process -FilePath "msiexec.exe" -ArgumentList "/i `"$($MSI.FullName)`" /quiet /norestart" -Wait -NoNewWindow } # Check if ICD.exe exists if (Test-Path -Path $ICDPath) { Write-EnhancedLog -Message "ICD.exe found at: $ICDPath" -Level "INFO" } else { throw "ICD.exe not found at: $ICDPath" } } catch { Write-EnhancedLog -Message "An error occurred while processing the Install-ADKFromMSI function: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting Install-ADKFromMSI function" -Level "INFO" } } # # Example usage # $installParams = @{ # OfflinePath = "$env:TEMP\ADKOffline\Installers" # ICDPath = "C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Imaging and Configuration Designer\x86\ICD.exe" # } # Install-ADKFromMSI @installParams #EndRegion '.\Public\Install-ADKFromMSI.ps1' 64 #Region '.\Public\Install-OneDrive.ps1' -1 function Install-OneDrive { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$MigrationPath, [Parameter(Mandatory = $false)] [bool]$OneDriveKFM = $false, [Parameter(Mandatory = $true)] [string]$ODSetupUri, [Parameter(Mandatory = $true)] [string]$ODSetupFile, [Parameter(Mandatory = $true)] [string]$ODRegKey, [Parameter(Mandatory = $true)] [string]$OneDriveExePath, [Parameter(Mandatory = $true)] [string]$ScheduledTaskName, [Parameter(Mandatory = $true)] [string]$ScheduledTaskDescription, [Parameter(Mandatory = $false)] [string]$ScheduledTaskArgumentList, [Parameter(Mandatory = $true)] [string]$SetupArgumentList ) Begin { Write-EnhancedLog -Message "Starting Install-OneDrive function" -Level "INFO" Log-Params -Params @{ MigrationPath = $MigrationPath OneDriveKFM = $OneDriveKFM ODSetupUri = $ODSetupUri ODSetupFile = $ODSetupFile ODRegKey = $ODRegKey OneDriveExePath = $OneDriveExePath ScheduledTaskName = $ScheduledTaskName ScheduledTaskDescription = $ScheduledTaskDescription # ScheduledTaskArgumentList = $ScheduledTaskArgumentList SetupArgumentList = $SetupArgumentList } $ODSetupPath = Join-Path -Path $MigrationPath -ChildPath $ODSetupFile $ODSetupVersion = $null } Process { try { if (Test-Path -Path $ODSetupPath) { $ODSetupVersion = (Get-ChildItem -Path $ODSetupPath).VersionInfo.FileVersion } if (-not $ODSetupVersion) { Invoke-WebRequest -Uri $ODSetupUri -OutFile $ODSetupPath $ODSetupVersion = (Get-ChildItem -Path $ODSetupPath).VersionInfo.FileVersion } $InstalledVer = if (Test-Path -Path $ODRegKey) { Get-ItemPropertyValue -Path $ODRegKey -Name Version } else { [System.Version]::new("0.0.0.0") } if (-not $InstalledVer -or ([System.Version]$InstalledVer -lt [System.Version]$ODSetupVersion)) { Write-EnhancedLog -Message "Installing OneDrive setup" -Level "INFO" Start-Process -FilePath $ODSetupPath -ArgumentList $SetupArgumentList -Wait -NoNewWindow } elseif ($OneDriveKFM) { Write-EnhancedLog -Message "OneDrive already installed, performing KFM sync if required" -Level "INFO" $ODProcess = Get-Process -Name OneDrive -ErrorAction SilentlyContinue if ($ODProcess) { $ODProcess | Stop-Process -Confirm:$false -Force Start-Sleep -Seconds 5 Unregister-ScheduledTaskWithLogging -TaskName $ScheduledTaskName $CreateOneDriveRemediationTaskParams = @{ OneDriveExePath = $OneDriveExePath ScheduledTaskName = $ScheduledTaskName ScheduledTaskDescription = $ScheduledTaskDescription # ScheduledTaskArgumentList = $ScheduledTaskArgumentList } Create-OneDriveRemediationTask @CreateOneDriveRemediationTaskParams } } } catch { Write-EnhancedLog -Message "An error occurred in Install-OneDrive function: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting Install-OneDrive function" -Level "INFO" } } # $InstallOneDriveParams = @{ # MigrationPath = "C:\ProgramData\AADMigration" # OneDriveKFM = $true # ODSetupUri = "https://go.microsoft.com/fwlink/?linkid=844652" # ODSetupFile = "Files\OneDriveSetup.exe" # ODRegKey = "HKLM:\SOFTWARE\Microsoft\OneDrive" # OneDriveExePath = "C:\Program Files\Microsoft OneDrive\OneDrive.exe" # ScheduledTaskName = "OneDriveRemediation" # ScheduledTaskDescription = "Restart OneDrive to kick off KFM sync" # ScheduledTaskArgumentList = "" # SetupArgumentList = "/allusers" # } # Install-OneDrive @InstallOneDriveParams #EndRegion '.\Public\Install-OneDrive.ps1' 120 #Region '.\Public\Main-MigrateToAADJOnly.ps1' -1 function Main-MigrateToAADJOnly { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$PPKGName, [Parameter(Mandatory = $false)] [string]$DomainLeaveUser, [Parameter(Mandatory = $false)] [string]$DomainLeavePassword, [Parameter(Mandatory = $true)] [string]$TempUser, [Parameter(Mandatory = $true)] [string]$TempUserPassword, [Parameter(Mandatory = $true)] [string]$ScriptPath ) Begin { Write-EnhancedLog -Message "Starting Main-MigrateToAADJOnly function" -Level "INFO" Log-Params -Params @{ PPKGName = $PPKGName; DomainLeaveUser = $DomainLeaveUser; DomainLeavePassword = $DomainLeavePassword; TempUser = $TempUser; TempUserPassword = $TempUserPassword; ScriptPath = $ScriptPath; } # Initialize steps $global:steps = @() Add-Step -description "Testing provisioning package" -action { $TestProvisioningPackParams = @{ PPKGName = $PPKGName } Test-ProvisioningPack @TestProvisioningPackParams } # Add-Step -description "Adding local user" -action { Add-LocalUser -TempUser $TempUser -TempUserPassword $TempUserPassword } Add-Step -description "Adding local user" -action { $AddLocalUserParams = @{ TempUser = $TempUser TempUserPassword = $TempUserPassword Description = "account for autologin" Group = "Administrators" } # Example usage with splatting Add-LocalUser @AddLocalUserParams } Add-Step -description "Setting autologin" -action { # Example usage with splatting $SetAutologinParams = @{ TempUser = $TempUser TempUserPassword = $TempUserPassword RegPath = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon' AutoAdminLogonName = 'AutoAdminLogon' AutoAdminLogonValue = '1' DefaultUsernameName = 'DefaultUsername' DefaultPasswordName = 'DefaultPassword' } Set-Autologin @SetAutologinParams } Add-Step -description "Disabling OOBE privacy" -action { # Example usage with splatting $DisableOOBEPrivacyParams = @{ OOBERegistryPath = 'HKLM:\Software\Policies\Microsoft\Windows\OOBE' OOBEName = 'DisablePrivacyExperience' OOBEValue = '1' AnimationRegistryPath = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon' AnimationName = 'EnableFirstLogonAnimation' AnimationValue = '0' LockRegistryPath = 'HKLM:\Software\Policies\Microsoft\Windows\Personalization' LockName = 'NoLockScreen' LockValue = '1' } Disable-OOBEPrivacy @DisableOOBEPrivacyParams } Add-Step -description "Setting RunOnce script" -action { # Example usage with splatting $SetRunOnceParams = @{ ScriptPath = $ScriptPath RunOnceKey = "HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce" PowershellPath = "C:\Windows\System32\WindowsPowerShell\v1.0\Powershell.exe" ExecutionPolicy = "Unrestricted" RunOnceName = "NextRun" } Set-RunOnce @SetRunOnceParams } Add-Step -description "Suspending BitLocker With Reboot Count" -action { # Example usage with splatting $SuspendBitLockerWithRebootParams = @{ MountPoint = "C:" RebootCount = 3 } Suspend-BitLockerWithReboot @SuspendBitLockerWithRebootParams } Add-Step -description "Removing Intune management" -action { # $RemoveCompanyPortalParams = @{ # AppxPackageName = "Microsoft.CompanyPortal" # } # Remove-CompanyPortal @RemoveCompanyPortalParams $RemoveIntuneMgmtParams = @{ OMADMPath = "HKLM:\SOFTWARE\Microsoft\Provisioning\OMADM\Accounts\*" EnrollmentBasePath = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Enrollments" TrackedBasePath = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\EnterpriseResourceManager\Tracked" PolicyManagerBasePath = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PolicyManager" ProvisioningBasePath = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Provisioning" CertCurrentUserPath = "cert:\CurrentUser" CertLocalMachinePath = "cert:\LocalMachine" TaskPathBase = "\Microsoft\Windows\EnterpriseMgmt" MSDMProviderID = "MS DM Server" RegistryPathsToRemove = @( "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Enrollments", "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Enrollments\Status", "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\EnterpriseResourceManager\Tracked", "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PolicyManager\AdmxInstalled", "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PolicyManager\Providers", "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Provisioning\OMADM\Accounts", "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Provisioning\OMADM\Logger", "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Provisioning\OMADM\Sessions" ) UserCertIssuer = "CN=SC_Online_Issuing" DeviceCertIssuers = @("CN=Microsoft Intune Root Certification Authority", "CN=Microsoft Intune MDM Device CA") } Remove-IntuneMgmt @RemoveIntuneMgmtParams } Add-Step -description "Removing hybrid join" -action { Remove-Hybrid } Add-Step -description "Removing AD join" -action { $RemoveADJoinParams = @{ # DomainLeaveUser = $DomainLeaveUser # DomainLeavePassword = $DomainLeavePassword TempUser = $TempUser TempUserPassword = $TempUserPassword ComputerName = "localhost" TaskName = "AADM Launch PSADT for Interactive Migration" } Remove-ADJoin @RemoveADJoinParams } } Process { try { foreach ($step in $global:steps) { Log-And-Execute-Step -Step $step } } catch { Write-EnhancedLog -Message "An error occurred: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting Main-MigrateToAADJOnly function" -Level "INFO" } } # $MainMigrateParams = @{ # PPKGName = "YourProvisioningPackName" # DomainLeaveUser = "YourDomainUser" # DomainLeavePassword = "YourDomainPassword" # TempUser = "YourTempUser" # TempUserPassword = "YourTempUserPassword" # ScriptPath = "C:\ProgramData\AADMigration\Scripts\PostRunOnce.ps1" # } # Main-MigrateToAADJOnly @MainMigrateParams #EndRegion '.\Public\Main-MigrateToAADJOnly.ps1' 199 #Region '.\Public\New-MigrationTask.ps1' -1 function New-MigrationTask { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$StartBoundary, [Parameter(Mandatory = $true)] [string]$ScriptPath, [Parameter(Mandatory = $true)] [string]$TaskPath, [Parameter(Mandatory = $true)] [string]$TaskName, [Parameter(Mandatory = $true)] [string]$Description, [Parameter(Mandatory = $true)] [string]$UserId, [Parameter(Mandatory = $true)] [string]$RunLevel, [Parameter(Mandatory = $true)] [string]$Delay, [Parameter(Mandatory = $true)] [string]$ExecutePath, [Parameter(Mandatory = $true)] [string]$Arguments ) Begin { Write-EnhancedLog -Message "Starting New-MigrationTask function" -Level "INFO" Log-Params -Params @{ StartBoundary = $StartBoundary ScriptPath = $ScriptPath TaskPath = $TaskPath TaskName = $TaskName Description = $Description UserId = $UserId RunLevel = $RunLevel Delay = $Delay ExecutePath = $ExecutePath Arguments = $Arguments } } Process { try { $action = New-ScheduledTaskAction -Execute $ExecutePath -Argument $Arguments $trigger = New-ScheduledTaskTrigger -AtLogOn $trigger.Delay = $Delay $trigger.StartBoundary = $StartBoundary $principal = New-ScheduledTaskPrincipal -UserId $UserId -RunLevel $RunLevel Register-ScheduledTask -Principal $principal -Action $action -Trigger $trigger -TaskName $TaskName -Description $Description -TaskPath $TaskPath } catch { Write-EnhancedLog -Message "An error occurred while creating the migration task: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting New-MigrationTask function" -Level "INFO" } } # Define parameters # $MigrationTaskParams = @{ # StartBoundary = "2024-07-11T12:00:00" # ScriptPath = "C:\ProgramData\AADMigration\Scripts\Launch-DeployApplication_SchTask.ps1" # TaskPath = "AAD Migration" # TaskName = "AADM Launch PSADT for Interactive Migration" # Description = "AADM Launch PSADT for Interactive Migration" # UserId = "SYSTEM" # RunLevel = "Highest" # Delay = "PT1M" # ExecutePath = "PowerShell.exe" # Arguments = "-executionpolicy Bypass -file `"$ScriptPath`"" # } # # Example usage with splatting # New-MigrationTask @MigrationTaskParams #EndRegion '.\Public\New-MigrationTask.ps1' 89 #Region '.\Public\PostRunOnce.ps1' -1 function PostRunOnce { [CmdletBinding()] param () Begin { Write-EnhancedLog -Message "Starting PostRunOnce function" -Level "INFO" } Process { try { Start-Transcript -Path C:\ProgramData\AADMigration\Logs\AD2AADJ-R1.txt -NoClobber $MigrationConfig = Import-LocalizedData -BaseDirectory "C:\ProgramData\AADMigration\scripts" -FileName "MigrationConfig.psd1" $PPKGName = $MigrationConfig.ProvisioningPack $MigrationPath = $MigrationConfig.MigrationPath # Block user input $code = @" [DllImport("user32.dll")] public static extern bool BlockInput(bool fBlockIt); "@ $userInput = Add-Type -MemberDefinition $code -Name Blocker -Namespace UserInput -PassThru $null = $userInput::BlockInput($true) # Display form with user input block message [void][reflection.assembly]::LoadWithPartialName("System.Drawing") [void][reflection.assembly]::LoadWithPartialName("System.Windows.Forms") $file = Get-Item "C:\ProgramData\AADMigration\Files\MigrationInProgress.bmp" $img = [System.Drawing.Image]::FromFile((Get-Item $file)) [System.Windows.Forms.Application]::EnableVisualStyles() $form = New-Object Windows.Forms.Form $form.Text = "Migration in Progress" $form.WindowState = 'Maximized' $form.BackColor = "#000000" $form.TopMost = $true $pictureBox = New-Object Windows.Forms.PictureBox $pictureBox.Width = $img.Size.Width $pictureBox.Height = $img.Size.Height $pictureBox.Dock = "Fill" $pictureBox.SizeMode = "StretchImage" $pictureBox.Image = $img $form.Controls.Add($pictureBox) $form.Add_Shown({ $form.Activate() }) $form.Show() Write-EnhancedLog -Message "Writing Run Once for Post Reboot 2" -Level "INFO" $RunOnceKey = "HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce" Set-ItemProperty -Path $RunOnceKey -Name "NextRun" -Value ("C:\Windows\System32\WindowsPowerShell\v1.0\Powershell.exe -executionPolicy Unrestricted -File C:\ProgramData\AADMigration\Scripts\PostRunOnce2.ps1") # Install Provisioning PPKG Write-EnhancedLog -Message "Installing Provisioning PPKG" -Level "INFO" Install-ProvisioningPackage -PackagePath "$MigrationPath\Files\$PPKGName" -ForceInstall -QuietInstall Stop-Transcript $null = $userInput::BlockInput($false) $form.Close() Restart-Computer } catch { Write-EnhancedLog -Message "An error occurred during the migration process: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting PostRunOnce function" -Level "INFO" } } # Example usage # PostRunOnce #EndRegion '.\Public\PostRunOnce.ps1' 76 #Region '.\Public\PostRunOnce2.ps1' -1 function PostRunOnce2 { [CmdletBinding()] param () Begin { Write-EnhancedLog -Message "Starting PostRunOnce2 function" -Level "INFO" } Process { try { # Start-Transcript -Path C:\ProgramData\AADMigration\Logs\AD2AADJ-R2.txt -Append -Verbose # Block user input $code = @" [DllImport("user32.dll")] public static extern bool BlockInput(bool fBlockIt); "@ $userInput = Add-Type -MemberDefinition $code -Name Blocker -Namespace UserInput -PassThru $null = $userInput::BlockInput($true) # Display form with user input block message [void][reflection.assembly]::LoadWithPartialName("System.Drawing") [void][reflection.assembly]::LoadWithPartialName("System.Windows.Forms") $file = Get-Item "C:\ProgramData\AADMigration\Files\MigrationInProgress.bmp" $img = [System.Drawing.Image]::FromFile((Get-Item $file)) [System.Windows.Forms.Application]::EnableVisualStyles() $form = New-Object Windows.Forms.Form $form.Text = "Migration in Progress" $form.WindowState = 'Maximized' $form.BackColor = "#000000" $form.TopMost = $true $pictureBox = New-Object Windows.Forms.PictureBox $pictureBox.Width = $img.Size.Width $pictureBox.Height = $img.Size.Height $pictureBox.Dock = "Fill" $pictureBox.SizeMode = "StretchImage" $pictureBox.Image = $img $form.Controls.Add($pictureBox) $form.Add_Shown({ $form.Activate() }) $form.Show() # Function to set registry values function Set-RegistryValue { [CmdletBinding()] param ( [string]$RegKeyPath, [string]$RegValName, [string]$RegValType, [string]$RegValData ) # Test to see if Edge key exists, if it does not exist create it $RegKeyPathExists = Test-Path -Path $RegKeyPath if (-not $RegKeyPathExists) { New-Item -Path $RegKeyPath -Force | Out-Null } # Check to see if value exists try { $CurrentValue = Get-ItemPropertyValue -Path $RegKeyPath -Name $RegValName } catch { # If value does not exist an error would be thrown, catch error and create key Set-ItemProperty -Path $RegKeyPath -Name $RegValName -Type $RegValType -Value $RegValData -Force } if ($CurrentValue -ne $RegValData) { # If value exists but data is wrong, update the value Set-ItemProperty -Path $RegKeyPath -Name $RegValName -Type $RegValType -Value $RegValData -Force } } Write-EnhancedLog -Message "Creating scheduled task to run PostRunOnce3" -Level "INFO" $TaskPath = "AAD Migration" $TaskName = "Run Post-migration cleanup" $ScriptPath = "C:\ProgramData\AADMigration\Scripts" $ScriptName = "PostRunOnce3.ps1" $arguments = "-executionpolicy Bypass -file $ScriptPath\$ScriptName" $action = New-ScheduledTaskAction -Execute 'PowerShell.exe' -Argument $arguments $trigger = New-ScheduledTaskTrigger -AtLogOn $principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -RunLevel Highest $Task = Register-ScheduledTask -Principal $principal -Action $action -Trigger $trigger -TaskName $TaskName -Description "Run post AAD Migration cleanup" -TaskPath $TaskPath Write-EnhancedLog -Message "Escrowing current Numeric Key" -Level "INFO" function Test-Bitlocker ($BitlockerDrive) { # Tests the drive for existing Bitlocker key protectors try { Get-BitLockerVolume -MountPoint $BitlockerDrive -ErrorAction Stop } catch { Write-Output "Bitlocker was not found protecting the $BitlockerDrive drive. Terminating script!" } } function Get-KeyProtectorId ($BitlockerDrive) { # Fetches the key protector ID of the drive $BitLockerVolume = Get-BitLockerVolume -MountPoint $BitlockerDrive $KeyProtector = $BitLockerVolume.KeyProtector | Where-Object { $_.KeyProtectorType -eq 'RecoveryPassword' } return $KeyProtector.KeyProtectorId } function Invoke-BitlockerEscrow ($BitlockerDrive, $BitlockerKey) { # Escrow the key into Azure AD try { BackupToAAD-BitLockerKeyProtector -MountPoint $BitlockerDrive -KeyProtectorId $BitlockerKey -ErrorAction SilentlyContinue Write-Output "Attempted to escrow key in Azure AD - Please verify manually!" } catch { Write-Error "Debug" } } $BitlockerVolumes = Get-BitLockerVolume $BitlockerVolumes | ForEach-Object { $MountPoint = $_.MountPoint $RecoveryKey = [string]($_.KeyProtector).RecoveryPassword if ($RecoveryKey.Length -gt 5) { $DriveLetter = $MountPoint Write-Output $DriveLetter Test-Bitlocker -BitlockerDrive $DriveLetter $KeyProtectorId = Get-KeyProtectorId -BitlockerDrive $DriveLetter Invoke-BitlockerEscrow -BitlockerDrive $DriveLetter -BitlockerKey $KeyProtectorId } } Write-EnhancedLog -Message "Setting registry key to disable AutoAdminLogon" -Level "INFO" Set-RegistryValue -RegKeyPath "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -RegValName "AutoAdminLogon" -RegValType "DWORD" -RegValData "0" Write-EnhancedLog -Message "Setting key to not show last logged in user" -Level "INFO" Set-RegistryValue -RegKeyPath "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -RegValName "dontdisplaylastusername" -RegValType "DWORD" -RegValData "1" Write-EnhancedLog -Message "Setting legal notice caption" -Level "INFO" Set-RegistryValue -RegKeyPath "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -RegValName "legalnoticecaption" -RegValType "String" -RegValData "Migration Completed" Write-EnhancedLog -Message "Setting legal notice text" -Level "INFO" Set-RegistryValue -RegKeyPath "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -RegValName "legalnoticetext" -RegValType "String" -RegValData "This PC has been migrated to Azure Active Directory. Please log in to Windows using your email address and password." Stop-Transcript $null = $userInput::BlockInput($false) $form.Close() Restart-Computer } catch { Write-EnhancedLog -Message "An error occurred in PostRunOnce2: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting PostRunOnce2 function" -Level "INFO" } } # Example usage # PostRunOnce2 #EndRegion '.\Public\PostRunOnce2.ps1' 159 #Region '.\Public\PostRunOnce3.ps1' -1 function PostRunOnce3 { [CmdletBinding()] param () Begin { Write-EnhancedLog -Message "Starting PostRunOnce3 function" -Level "INFO" } Process { try { # Start-Transcript -Path C:\ProgramData\AADMigration\Logs\AD2AADJ-R3.txt -Append -Force $MigrationConfig = Import-LocalizedData -BaseDirectory "C:\ProgramData\AADMigration\scripts" -FileName "MigrationConfig.psd1" $TempUser = $MigrationConfig.TempUser # Function to set registry values function Set-RegistryValue { [CmdletBinding()] param ( [string]$RegKeyPath, [string]$RegValName, [string]$RegValType, [string]$RegValData ) # Test to see if the registry key exists, if not, create it $RegKeyPathExists = Test-Path -Path $RegKeyPath if (-not $RegKeyPathExists) { New-Item -Path $RegKeyPath -Force | Out-Null } # Check to see if the value exists try { $CurrentValue = Get-ItemPropertyValue -Path $RegKeyPath -Name $RegValName } catch { # If the value does not exist, catch the error and create the key Set-ItemProperty -Path $RegKeyPath -Name $RegValName -Type $RegValType -Value $RegValData -Force } if ($CurrentValue -ne $RegValData) { # If the value exists but the data is wrong, update the value Set-ItemProperty -Path $RegKeyPath -Name $RegValName -Type $RegValType -Value $RegValData -Force } } # Clean up after ourselves # Remove local user account created for migration Remove-LocalUser -Name $TempUser # Remove autologon settings and default user and password from registry $RegPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" Set-ItemProperty -Path $RegPath -Name "AutoAdminLogon" -Value "0" -Type String Set-ItemProperty -Path $RegPath -Name "DefaultUsername" -Value $null -Type String Set-ItemProperty -Path $RegPath -Name "DefaultPassword" -Value $null -Type String # Remove setting to not show local user Write-EnhancedLog -Message "Setting key to show last logged in user" -Level "INFO" Set-RegistryValue -RegKeyPath "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -RegValName "dontdisplaylastusername" -RegValType "DWORD" -RegValData "0" # Clear legal notice caption Write-EnhancedLog -Message "Setting legal notice caption" -Level "INFO" Set-RegistryValue -RegKeyPath "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -RegValName "legalnoticecaption" -RegValType "String" -RegValData $null # Clear legal notice text Write-EnhancedLog -Message "Setting legal notice text" -Level "INFO" Set-RegistryValue -RegKeyPath "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -RegValName "legalnoticetext" -RegValType "String" -RegValData $null # Re-enable lock screen Write-EnhancedLog -Message "Re-enabling lock screen" -Level "INFO" Set-RegistryValue -RegKeyPath "HKLM:\Software\Policies\Microsoft\Windows\Personalization" -RegValName "NoLockScreen" -RegValType "DWORD" -RegValData "0" # Enumerate local user accounts and disable them $Users = Get-LocalUser | Where-Object { $_.Enabled -eq $true -and $_.Name -notlike 'default*' } foreach ($User in $Users) { Write-EnhancedLog -Message "Disabling local user account $User" -Level "INFO" Disable-LocalUser -Name $User.Name } # Delete scheduled tasks created for migration $taskPath = "AAD Migration" $tasks = Get-ScheduledTask -TaskPath "\$taskPath\" foreach ($Task in $tasks) { Unregister-ScheduledTask -TaskName $Task.TaskName -Confirm:$false } $scheduler = New-Object -ComObject "Schedule.Service" $scheduler.Connect() $rootFolder = $scheduler.GetFolder("\") $rootFolder.DeleteFolder($taskPath, $null) # Delete migration files, leave log folder # Remove PPKG files, which include nested credentials $FileName = "C:\ProgramData\AADMigration\Files" if (Test-Path -Path $FileName) { Remove-Item -Path $FileName -Recurse -Force } $FileName = "C:\ProgramData\AADMigration\Scripts" if (Test-Path -Path $FileName) { Remove-Item -Path $FileName -Recurse -Force } $FileName = "C:\ProgramData\AADMigration\Toolkit" if (Test-Path -Path $FileName) { Remove-Item -Path $FileName -Recurse -Force } # Launch OneDrive # Start-Process -FilePath "C:\Program Files (x86)\Microsoft OneDrive\OneDrive.exe" Stop-Transcript } catch { Write-EnhancedLog -Message "An error occurred in PostRunOnce3: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting PostRunOnce3 function" -Level "INFO" } } # Example usage # PostRunOnce3 #EndRegion '.\Public\PostRunOnce3.ps1' 125 #Region '.\Public\Prepare-AADMigration.ps1' -1 function Prepare-AADMigration { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$MigrationPath, [Parameter(Mandatory = $true)] [string]$PSScriptbase, [Parameter(Mandatory = $true)] [string]$ConfigBaseDirectory, [Parameter(Mandatory = $true)] [string]$ConfigFileName, [Parameter(Mandatory = $true)] [string]$TenantID, [Parameter(Mandatory = $true)] [bool]$OneDriveKFM, [Parameter(Mandatory = $true)] [bool]$InstallOneDrive ) Begin { Write-EnhancedLog -Message "Starting Prepare-AADMigration function" -Level "INFO" Log-Params -Params @{ MigrationPath = $MigrationPath PSScriptbase = $PSScriptbase ConfigBaseDirectory = $ConfigBaseDirectory ConfigFileName = $ConfigFileName TenantID = $TenantID OneDriveKFM = $OneDriveKFM InstallOneDrive = $InstallOneDrive } } Process { try { # Ensure the target directory exists if (-not (Test-Path -Path $MigrationPath)) { New-Item -Path $MigrationPath -ItemType Directory -Force | Out-Null } # Copy the entire content of $PSScriptRoot to $MigrationPath # Define the source and destination paths $sourcePath1 = $PSScriptbase $sourcePath2 = "C:\code\modules" $destinationPath1 = $MigrationPath $destinationPath2 = "$MigrationPath\modules" # Copy files from $PSScriptRoot using the Copy-FilesToPath function # Copy-FilesToPath -SourcePath $sourcePath1 -DestinationPath $destinationPath1 Stop-ProcessesUsingOneDriveLib -OneDriveLibPath "C:\ProgramData\AADMigration\Files\OneDriveLib.dll" # $DBG Remove-ScheduledTaskFilesWithLogging -Path $destinationPath1 Copy-FilesToPathWithKill -SourcePath $sourcePath1 -DestinationPath $destinationPath1 # Verify the copy operation for $PSScriptRoot Verify-CopyOperation -SourcePath $sourcePath1 -DestinationPath $destinationPath1 # Copy files from C:\code\modules using the Copy-FilesToPath function # Copy-FilesToPath -SourcePath $sourcePath2 -DestinationPath $destinationPath2 Copy-FilesToPathWithKill -SourcePath $sourcePath2 -DestinationPath $destinationPath2 # Verify the copy operation for C:\code\modules Verify-CopyOperation -SourcePath $sourcePath2 -DestinationPath $destinationPath2 # $DBG Write-EnhancedLog -Message "Copied content from $PSScriptRoot to $MigrationPath" -Level "INFO" # $DBG # Import migration configuration $MigrationConfig = Import-LocalizedData -BaseDirectory $ConfigBaseDirectory -FileName $ConfigFileName $TenantID = $MigrationConfig.TenantID $OneDriveKFM = $MigrationConfig.UseOneDriveKFM $InstallOneDrive = $MigrationConfig.InstallOneDrive # $DBG # Set OneDrive KFM settings if required if ($OneDriveKFM) { # $TenantID = "YourTenantID" $RegistrySettings = @( @{ RegValueName = "AllowTenantList" RegValType = "STRING" RegValData = $TenantID }, @{ RegValueName = "SilentAccountConfig" RegValType = "DWORD" RegValData = "1" }, @{ RegValueName = "KFMOptInWithWizard" RegValType = "STRING" RegValData = $TenantID }, @{ RegValueName = "KFMSilentOptIn" RegValType = "STRING" RegValData = $TenantID }, @{ RegValueName = "KFMSilentOptInDesktop" RegValType = "DWORD" RegValData = "1" }, @{ RegValueName = "KFMSilentOptInDocuments" RegValType = "DWORD" RegValData = "1" }, @{ RegValueName = "KFMSilentOptInPictures" RegValType = "DWORD" RegValData = "1" } ) $SetODKFMRegistrySettingsParams = @{ TenantID = $TenantID RegKeyPath = "HKLM:\SOFTWARE\Policies\Microsoft\OneDrive" RegistrySettings = $RegistrySettings } # $DBG Set-ODKFMRegistrySettings @SetODKFMRegistrySettingsParams # $DBG Unregister-ScheduledTaskWithLogging -TaskName "AADM Get OneDrive Sync Status" # Example usage with splatting $CreateOneDriveSyncStatusTaskParams = @{ TaskPath = "AAD Migration" TaskName = "AADM Get OneDrive Sync Status" ScriptDirectory = "C:\ProgramData\AADMigration\Scripts" ScriptName = "Check-OneDriveSyncStatus.ps1" TaskArguments = "-NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -file `"{ScriptPath}`"" TaskRepetitionDuration = "P1D" TaskRepetitionInterval = "PT30M" TaskPrincipalGroupId = "BUILTIN\Users" PowerShellPath = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" TaskDescription = "Get current OneDrive Sync Status and write to event log" } Create-OneDriveSyncStatusTask @CreateOneDriveSyncStatusTaskParams # $DBG } # Install OneDrive if required if ($InstallOneDrive) { # Example usage $InstallOneDriveParams = @{ MigrationPath = "C:\ProgramData\AADMigration" OneDriveKFM = $true ODSetupUri = "https://go.microsoft.com/fwlink/?linkid=844652" ODSetupFile = "Files\OneDriveSetup.exe" ODRegKey = "HKLM:\SOFTWARE\Microsoft\OneDrive" OneDriveExePath = "C:\Program Files\Microsoft OneDrive\OneDrive.exe" ScheduledTaskName = "OneDriveRemediation" ScheduledTaskDescription = "Restart OneDrive to kick off KFM sync" # ScheduledTaskArgumentList = "" SetupArgumentList = "/allusers" } Install-OneDrive @InstallOneDriveParams $DBG } #Todo now we have OneDrive installed and running need to actually starting using our OneDrive for Business location on the local machine to copy user specific files into it as part of our On-prem AD to Entra ID migration prep so we need to copy the following PR4B projects from before # 1- copy Outlook Signatures # 2- copy Downloads folders # any other user specific files # copy Downloads folders Backup-DownloadsToOneDrive } catch { Write-EnhancedLog -Message "An error occurred in Prepare-AADMigration: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting Prepare-AADMigration function" -Level "INFO" } } # # Define parameters # $PrepareAADMigrationParams = @{ # MigrationPath = "C:\ProgramData\AADMigration" # PSScriptRoot = "C:\SourcePath" # ConfigBaseDirectory = "C:\ConfigDirectory\Scripts" # ConfigFileName = "MigrationConfig.psd1" # TenantID = "YourTenantID" # OneDriveKFM = $true # InstallOneDrive = $true # } # # Example usage with splatting # Prepare-AADMigration @PrepareAADMigrationParams #EndRegion '.\Public\Prepare-AADMigration.ps1' 237 #Region '.\Public\Prepare-DeviceMigration-Archive.ps1' -1 # function Prepare-DeviceMigration { # [CmdletBinding()] # param () # Begin { # Write-EnhancedLog -Message "Starting Prepare-DeviceMigration function" -Level "INFO" # } # Process { # try { # Start-Transcript -Path C:\ProgramData\AADMigration\Logs\AD2AADJ-Prep.txt -Append -Force # $MigrationConfig = Import-LocalizedData -BaseDirectory "." -FileName "MigrationConfig.psd1" # $MigrationPath = $MigrationConfig.MigrationPath # $TenantID = $MigrationConfig.TenantID # $OneDriveKFM = $MigrationConfig.UseOneDriveKFM # $InstallOneDrive = $MigrationConfig.InstallOneDrive # $StartBoundary = $MigrationConfig.StartBoundary # function Add-MigrationDirectory { # # Expand AAD Migration zip file to ProgramData # Expand-Archive -Path "$PSScriptRoot\AADMigration.zip" -DestinationPath C:\ProgramData -Force # Copy-Item -Path "$PSScriptRoot\MigrationConfig.psd1" -Destination "$MigrationPath\Module" # } # function Set-RegistryValue { # [CmdletBinding()] # param ( # [string]$RegKeyPath, # [string]$RegValName, # [string]$RegValType, # [string]$RegValData # ) # # Test to see if the registry key exists, if it does not, create it # $RegKeyPathExists = Test-Path -Path $RegKeyPath # if (-not $RegKeyPathExists) { # New-Item -Path $RegKeyPath -Force | Out-Null # } # # Check to see if the value exists # try { # $CurrentValue = Get-ItemPropertyValue -Path $RegKeyPath -Name $RegValName # } catch { # # If the value does not exist, catch the error and create the key # Set-ItemProperty -Path $RegKeyPath -Name $RegValName -Type $RegValType -Value $RegValData -Force # } # if ($CurrentValue -ne $RegValData) { # # If the value exists but the data is wrong, update the value # Set-ItemProperty -Path $RegKeyPath -Name $RegValName -Type $RegValType -Value $RegValData -Force # } # } # function Set-ODKFMSettings { # # Set registry values for enabling KFM to set tenant # Set-RegistryValue -RegKeyPath "HKLM:\SOFTWARE\Policies\Microsoft\OneDrive" -RegValName "AllowTenantList" -RegValType "STRING" -RegValData $TenantID # Set-RegistryValue -RegKeyPath "HKLM:\SOFTWARE\Policies\Microsoft\OneDrive" -RegValName "SilentAccountConfig" -RegValType "DWORD" -RegValData "1" # Set-RegistryValue -RegKeyPath "HKLM:\SOFTWARE\Policies\Microsoft\OneDrive" -RegValName "KFMOptInWithWizard" -RegValType "STRING" -RegValData $TenantID # Set-RegistryValue -RegKeyPath "HKLM:\SOFTWARE\Policies\Microsoft\OneDrive" -RegValName "KFMSilentOptIn" -RegValType "STRING" -RegValData $TenantID # Set-RegistryValue -RegKeyPath "HKLM:\SOFTWARE\Policies\Microsoft\OneDrive" -RegValName "KFMSilentOptInDesktop" -RegValType "DWORD" -RegValData "1" # Set-RegistryValue -RegKeyPath "HKLM:\SOFTWARE\Policies\Microsoft\OneDrive" -RegValName "KFMSilentOptInDocuments" -RegValType "DWORD" -RegValData "1" # Set-RegistryValue -RegKeyPath "HKLM:\SOFTWARE\Policies\Microsoft\OneDrive" -RegValName "KFMSilentOptInPictures" -RegValType "DWORD" -RegValData "1" # # Create EventLog Source # New-EventLog -LogName 'Application' -Source 'AAD_Migration_Script' -ErrorAction Stop # # Create scheduled task to check OneDrive sync status # $TaskPath = "AAD Migration" # $TaskName = "AADM Get OneDrive Sync Status" # $ScriptPath = "C:\ProgramData\AADMigration\Scripts" # $ScriptName = "Check-OneDriveSyncStatus.ps1" # $arguments = "-NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -file $ScriptPath\$ScriptName" # $action = New-ScheduledTaskAction -Execute 'PowerShell.exe' -Argument $arguments # $trigger = New-ScheduledTaskTrigger -AtLogOn # $trigger.Delay = 'PT1M' # $principal = New-ScheduledTaskPrincipal -GroupId "BUILTIN\Users" # $Task = Register-ScheduledTask -Principal $principal -Action $action -Trigger $trigger -TaskName $TaskName -Description "Get current OneDrive Sync Status and write to event log" -TaskPath $TaskPath # $Task.Triggers.Repetition.Duration = "P1D" # $Task.Triggers.Repetition.Interval = "PT30M" # $Task | Set-ScheduledTask # } # function Install-OneDrive { # # Check for OneDrive machine-wide installer, check version number if it exists # $ODSetupVersion = (Get-ChildItem -Path "$PSScriptRoot\AADMigration\Files\OneDriveSetup.exe").VersionInfo.FileVersion # if (-not $ODSetupVersion) { # Invoke-WebRequest -Uri "https://go.microsoft.com/fwlink/?linkid=844652" -OutFile "$PSScriptRoot\Files\OneDriveSetup.exe" -Wait # $ODSetupVersion = (Get-ChildItem -Path "$PSScriptRoot\Files\OneDriveSetup.exe").VersionInfo.FileVersion # } # $ODRegKey = "HKLM:\SOFTWARE\Microsoft\OneDrive" # $InstalledVer = Get-ItemPropertyValue -Path $ODRegKey -Name Version # if (-not $ODRegKey -or ([System.Version]$InstalledVer -lt [System.Version]$ODSetupVersion)) { # # Install OneDrive setup # $Installer = "$PSScriptRoot\Files\OneDriveSetup.exe" # $Arguments = "/allusers" # Start-Process -FilePath $Installer -ArgumentList $Arguments # } elseif ($OneDriveKFM) { # # If OneDrive is already installed, stop the process and restart to kick off KFM sync if required # Get-Process -Name OneDrive | Stop-Process -Confirm:$false -Force # Start-Sleep -Seconds 5 # $action = New-ScheduledTaskAction -Execute "C:\Program Files\Microsoft Onedrive\OneDrive.exe" # $trigger = New-ScheduledTaskTrigger -AtLogOn # $principal = New-ScheduledTaskPrincipal -UserId (Get-CimInstance -ClassName Win32_ComputerSystem | Select-Object -ExpandProperty UserName) # $task = New-ScheduledTask -Action $action -Trigger $trigger -Principal $principal # Register-ScheduledTask -TaskName OneDriveRemediation -InputObject $task # Start-ScheduledTask -TaskName OneDriveRemediation # Start-Sleep -Seconds 5 # Unregister-ScheduledTask -TaskName OneDriveRemediation -Confirm:$false # } # } # function New-MigrationTask { # # Create Scheduled task to launch interactive migration task # $TaskPath = "AAD Migration" # $TaskName = "AADM Launch PSADT for Interactive Migration" # $ScriptPath = "C:\ProgramData\AADMigration\Scripts" # $ScriptName = "Launch-DeployApplication_SchTask.ps1" # $arguments = "-executionpolicy Bypass -file $ScriptPath\$ScriptName" # $action = New-ScheduledTaskAction -Execute 'PowerShell.exe' -Argument $arguments # $trigger = New-ScheduledTaskTrigger -AtLogOn # $trigger.Delay = 'PT1M' # $trigger.StartBoundary = $StartBoundary # $principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -RunLevel Highest # $Task = Register-ScheduledTask -Principal $principal -Action $action -Trigger $trigger -TaskName $TaskName -Description "AADM Launch PSADT for Interactive Migration" -TaskPath $TaskPath # } # Add-MigrationDirectory # New-MigrationTask # if ($OneDriveKFM) { # Set-ODKFMSettings # } # if ($InstallOneDrive) { # Install-OneDrive # } # Stop-Transcript # } catch { # Write-EnhancedLog -Message "An error occurred in Prepare-DeviceMigration: $($_.Exception.Message)" -Level "ERROR" # Handle-Error -ErrorRecord $_ # } # } # End { # Write-EnhancedLog -Message "Exiting Prepare-DeviceMigration function" -Level "INFO" # } # } # # Example usage # # Prepare-DeviceMigration #EndRegion '.\Public\Prepare-DeviceMigration-Archive.ps1' 159 #Region '.\Public\Prepare-SolutionDirectory.ps1' -1 function Prepare-SolutionDirectory { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$ToolkitFolder, [Parameter(Mandatory = $true)] [string]$FilesFolder ) Begin { Write-EnhancedLog -Message "Starting Prepare-SolutionDirectory function" -Level "INFO" Log-Params -Params @{ ToolkitFolder = $ToolkitFolder FilesFolder = $FilesFolder } } Process { try { # Create necessary directories New-Item -ItemType Directory -Path $ToolkitFolder -Force New-Item -ItemType Directory -Path $FilesFolder -Force } catch { Write-EnhancedLog -Message "An error occurred while processing the Prepare-SolutionDirectory function: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting Prepare-SolutionDirectory function" -Level "INFO" } } # Example usage # Prepare-SolutionDirectory -ToolkitFolder "C:\path\to\toolkit" -FilesFolder "C:\path\to\files" #EndRegion '.\Public\Prepare-SolutionDirectory.ps1' 37 #Region '.\Public\Remove-ADJoin.ps1' -1 function Remove-ADJoin { [CmdletBinding()] param ( [Parameter(Mandatory = $false)] [string]$DomainLeaveUser, [Parameter(Mandatory = $false)] [string]$DomainLeavePassword, [Parameter(Mandatory = $true)] [string]$TempUser, [Parameter(Mandatory = $true)] [string]$TempUserPassword, [Parameter(Mandatory = $true)] [string]$ComputerName = "localhost", [Parameter(Mandatory = $true)] [string]$TaskName = "AADM Launch PSADT for Interactive Migration" ) Begin { Write-EnhancedLog -Message "Starting Remove-ADJoin function" -Level "INFO" Log-Params -Params @{ DomainLeaveUser = $DomainLeaveUser DomainLeavePassword = $DomainLeavePassword TempUser = $TempUser TempUserPassword = $TempUserPassword ComputerName = $ComputerName TaskName = $TaskName } } Process { try { Write-EnhancedLog -Message "Checking if device is domain joined" -Level "INFO" $ComputerSystem = Get-WmiObject -Class Win32_ComputerSystem $Domain = $ComputerSystem.Domain $PartOfDomain = $ComputerSystem.PartOfDomain if ($PartOfDomain) { Write-EnhancedLog -Message "Computer is domain member, removing domain membership" -Level "INFO" if (Test-Connection -ComputerName $Domain -Count 1 -Quiet) { Write-EnhancedLog -Message "Connected to domain, attempting to leave domain." -Level "INFO" if ($DomainLeaveUser) { $SecurePassword = ConvertTo-SecureString -String $DomainLeavePassword -AsPlainText -Force $Credentials = New-Object System.Management.Automation.PSCredential($DomainLeaveUser, $SecurePassword) try { Remove-Computer -ComputerName $ComputerName -Credential $Credentials -Verbose -Force -ErrorAction Stop Disable-ScheduledTask -TaskName $TaskName Stop-Transcript Restart-Computer } catch { Write-EnhancedLog -Message "Leaving domain with domain credentials failed. Will leave domain with local account." -Level "ERROR" } } $SecurePassword = ConvertTo-SecureString -String $TempUserPassword -AsPlainText -Force $Credentials = New-Object System.Management.Automation.PSCredential($TempUser, $SecurePassword) $ConnectedAdapters = Get-NetAdapter | Where-Object { $_.MediaConnectionState -eq "Connected" } foreach ($Adapter in $ConnectedAdapters) { Write-EnhancedLog -Message "Disabling network adapter $($Adapter.Name)" -Level "INFO" Disable-NetAdapter -Name $Adapter.Name -Confirm:$false } Start-Sleep -Seconds 5 Remove-Computer -ComputerName $ComputerName -Credential $Credentials -Verbose -Force foreach ($Adapter in $ConnectedAdapters) { Write-EnhancedLog -Message "Enabling network adapter $($Adapter.Name)" -Level "INFO" Enable-NetAdapter -Name $Adapter.Name -Confirm:$false } Start-Sleep -Seconds 15 Write-EnhancedLog -Message "Computer removed from domain. Network adapters re-enabled. Restarting." -Level "INFO" Disable-ScheduledTask -TaskName $TaskName Stop-Transcript Restart-Computer } else { Write-Verbose "Removing computer from domain and forcing restart" Write-EnhancedLog -Message "Stopping transcript and calling Remove-Computer with -Restart switch." -Level "INFO" Stop-Transcript Remove-Computer -ComputerName $ComputerName -Credential $Credentials -Verbose -Force -ErrorAction Stop Disable-ScheduledTask -TaskName $TaskName Stop-Transcript Restart-Computer } } else { Write-EnhancedLog -Message "Computer is not a domain member, restarting computer." -Level "INFO" Disable-ScheduledTask -TaskName $TaskName Stop-Transcript Restart-Computer } } catch { Write-EnhancedLog -Message "An error occurred while removing AD join: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting Remove-ADJoin function" -Level "INFO" } } # $RemoveADJoinParams = @{ # DomainLeaveUser = "YourDomainUser" # DomainLeavePassword = "YourDomainPassword" # TempUser = "YourTempUser" # TempUserPassword = "YourTempUserPassword" # ComputerName = "localhost" # TaskName = "AADM Launch PSADT for Interactive Migration" # } # Remove-ADJoin @RemoveADJoinParams #EndRegion '.\Public\Remove-ADJoin.ps1' 121 #Region '.\Public\Remove-CompanyPortal.ps1' -1 function Remove-CompanyPortal { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$AppxPackageName ) Begin { Write-EnhancedLog -Message "Starting Remove-CompanyPortal function" -Level "INFO" Log-Params -Params @{ AppxPackageName = $AppxPackageName } } Process { try { Write-EnhancedLog -Message "Removing AppxPackage: $AppxPackageName" -Level "INFO" Get-AppxPackage -AllUsers -Name $AppxPackageName | Remove-AppxPackage -Confirm:$false } catch { Write-EnhancedLog -Message "An error occurred while removing AppxPackage: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting Remove-CompanyPortal function" -Level "INFO" } } # $RemoveCompanyPortalParams = @{ # AppxPackageName = "Microsoft.CompanyPortal" # } # Remove-CompanyPortal @RemoveCompanyPortalParams #EndRegion '.\Public\Remove-CompanyPortal.ps1' 33 #Region '.\Public\Remove-Hybrid.ps1' -1 function Remove-Hybrid { [CmdletBinding()] param () Begin { Write-EnhancedLog -Message "Starting Remove-Hybrid function" -Level "INFO" } Process { try { Write-EnhancedLog -Message "Checking if device is Azure AD joined" -Level "INFO" $Dsregcmd = New-Object PSObject Dsregcmd /status | Where-Object { $_ -match ' : ' } | ForEach-Object { $Item = $_.Trim() -split '\s:\s' $Dsregcmd | Add-Member -MemberType NoteProperty -Name $($Item[0] -replace '[:\s]', '') -Value $Item[1] -ErrorAction SilentlyContinue } $AzureADJoined = $Dsregcmd.AzureAdJoined if ($AzureADJoined -eq 'Yes') { Write-EnhancedLog -Message "Device is Azure AD joined. Removing hybrid join." -Level "INFO" & "C:\Windows\System32\dsregcmd.exe" /leave } } catch { Write-EnhancedLog -Message "An error occurred while removing hybrid join: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting Remove-Hybrid function" -Level "INFO" } } # Example usage # Remove-Hybrid #EndRegion '.\Public\Remove-Hybrid.ps1' 37 #Region '.\Public\Remove-IntuneMgmt.ps1' -1 function Remove-IntuneMgmt { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$OMADMPath, [Parameter(Mandatory = $true)] [string]$EnrollmentBasePath, [Parameter(Mandatory = $true)] [string]$TrackedBasePath, [Parameter(Mandatory = $true)] [string]$PolicyManagerBasePath, [Parameter(Mandatory = $true)] [string]$ProvisioningBasePath, [Parameter(Mandatory = $true)] [string]$CertCurrentUserPath, [Parameter(Mandatory = $true)] [string]$CertLocalMachinePath, [Parameter(Mandatory = $true)] [string]$TaskPathBase, [Parameter(Mandatory = $true)] [string]$MSDMProviderID, [Parameter(Mandatory = $true)] [string[]]$RegistryPathsToRemove, [Parameter(Mandatory = $true)] [string]$UserCertIssuer, [Parameter(Mandatory = $true)] [string[]]$DeviceCertIssuers ) Begin { Write-EnhancedLog -Message "Starting Remove-IntuneMgmt function" -Level "INFO" Log-Params -Params @{ OMADMPath = $OMADMPath EnrollmentBasePath = $EnrollmentBasePath TrackedBasePath = $TrackedBasePath PolicyManagerBasePath = $PolicyManagerBasePath ProvisioningBasePath = $ProvisioningBasePath CertCurrentUserPath = $CertCurrentUserPath CertLocalMachinePath = $CertLocalMachinePath TaskPathBase = $TaskPathBase MSDMProviderID = $MSDMProviderID RegistryPathsToRemove = $RegistryPathsToRemove UserCertIssuer = $UserCertIssuer DeviceCertIssuers = $DeviceCertIssuers } } Process { try { Write-EnhancedLog -Message "Checking Intune enrollment status" -Level "INFO" $Account = (Get-ItemProperty -Path $OMADMPath -ErrorAction SilentlyContinue).PSChildName $Enrolled = $true $EnrollmentPath = "$EnrollmentBasePath\$Account" $EnrollmentUPN = (Get-ItemProperty -Path $EnrollmentPath -ErrorAction SilentlyContinue).UPN $ProviderID = (Get-ItemProperty -Path $EnrollmentPath -ErrorAction SilentlyContinue).ProviderID if (-not $EnrollmentUPN -or $ProviderID -ne $MSDMProviderID) { $Enrolled = $false } if ($Enrolled) { Write-EnhancedLog -Message "Device is enrolled in Intune. Proceeding with unenrollment." -Level "INFO" # Delete Task Schedule tasks Get-ScheduledTask -TaskPath "$TaskPathBase\$Account\*" | Unregister-ScheduledTask -Confirm:$false -ErrorAction SilentlyContinue # Delete registry keys foreach ($RegistryPath in $RegistryPathsToRemove) { Remove-Item -Path "$RegistryPath\$Account" -Recurse -Force -ErrorAction SilentlyContinue } # Delete enrollment certificates $UserCerts = Get-ChildItem -Path $CertCurrentUserPath -Recurse $IntuneCerts = $UserCerts | Where-Object { $_.Issuer -eq $UserCertIssuer } foreach ($Cert in $IntuneCerts) { $Cert | Remove-Item -Force } $DeviceCerts = Get-ChildItem -Path $CertLocalMachinePath -Recurse $IntuneCerts = $DeviceCerts | Where-Object { $DeviceCertIssuers -contains $_.Issuer } foreach ($Cert in $IntuneCerts) { $Cert | Remove-Item -Force -ErrorAction SilentlyContinue } } } catch { Write-EnhancedLog -Message "An error occurred while removing Intune management: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting Remove-IntuneMgmt function" -Level "INFO" } } # $RemoveIntuneMgmtParams = @{ # OMADMPath = "HKLM:\SOFTWARE\Microsoft\Provisioning\OMADM\Accounts\*" # EnrollmentBasePath = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Enrollments" # TrackedBasePath = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\EnterpriseResourceManager\Tracked" # PolicyManagerBasePath = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PolicyManager" # ProvisioningBasePath = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Provisioning" # CertCurrentUserPath = "cert:\CurrentUser" # CertLocalMachinePath = "cert:\LocalMachine" # TaskPathBase = "\Microsoft\Windows\EnterpriseMgmt" # MSDMProviderID = "MS DM Server" # RegistryPathsToRemove = @( # "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Enrollments", # "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Enrollments\Status", # "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\EnterpriseResourceManager\Tracked", # "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PolicyManager\AdmxInstalled", # "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PolicyManager\Providers", # "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Provisioning\OMADM\Accounts", # "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Provisioning\OMADM\Logger", # "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Provisioning\OMADM\Sessions" # ) # UserCertIssuer = "CN=SC_Online_Issuing" # DeviceCertIssuers = @("CN=Microsoft Intune Root Certification Authority", "CN=Microsoft Intune MDM Device CA") # } # Remove-IntuneMgmt @RemoveIntuneMgmtParams #EndRegion '.\Public\Remove-IntuneMgmt.ps1' 133 #Region '.\Public\Replace-BannerImage.ps1' -1 function Replace-BannerImage { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$Source, [Parameter(Mandatory = $true)] [string]$Destination ) Begin { Write-EnhancedLog -Message "Starting Replace-BannerImage function" -Level "INFO" Log-Params -Params @{ Source = $Source Destination = $Destination } } Process { try { # Replace the banner image in the toolkit folder Copy-Item -Path $Source -Destination $Destination -Force } catch { Write-EnhancedLog -Message "An error occurred while processing the Replace-BannerImage function: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting Replace-BannerImage function" -Level "INFO" } } # Example usage # Replace-BannerImage -Source 'C:\YourPath\YourBannerImage.png' -Destination 'C:\YourPath\Toolkit\AppDeployToolkit\AppDeployToolkitBanner.png' #EndRegion '.\Public\Replace-BannerImage.ps1' 36 #Region '.\Public\Replace-DeployApplicationPS1.ps1' -1 function Replace-DeployApplicationPS1 { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$Source, [Parameter(Mandatory = $true)] [string]$Destination ) Begin { Write-EnhancedLog -Message "Starting Replace-DeployApplicationPS1 function" -Level "INFO" Log-Params -Params @{ Source = $Source Destination = $Destination } } Process { try { # Replace Deploy-Application.ps1 in the toolkit folder Copy-Item -Path $Source -Destination $Destination -Force } catch { Write-EnhancedLog -Message "An error occurred while processing the Replace-DeployApplicationPS1 function: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting Replace-DeployApplicationPS1 function" -Level "INFO" } } # Example usage # Replace-DeployApplicationPS1 -Source 'C:\YourPath\Scripts\Deploy-Application.ps1' -Destination 'C:\YourPath\Toolkit\Deploy-Application.ps1' #EndRegion '.\Public\Replace-DeployApplicationPS1.ps1' 36 #Region '.\Public\Set-Autologin.ps1' -1 function Set-Autologin { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$TempUser, [Parameter(Mandatory = $true)] [string]$TempUserPassword, [Parameter(Mandatory = $true)] [string]$RegPath, [Parameter(Mandatory = $true)] [string]$AutoAdminLogonName, [Parameter(Mandatory = $true)] [string]$AutoAdminLogonValue, [Parameter(Mandatory = $true)] [string]$DefaultUsernameName, [Parameter(Mandatory = $true)] [string]$DefaultPasswordName ) Begin { Write-EnhancedLog -Message "Starting Set-Autologin function" -Level "INFO" Log-Params -Params @{ TempUser = $TempUser TempUserPassword = $TempUserPassword RegPath = $RegPath AutoAdminLogonName = $AutoAdminLogonName AutoAdminLogonValue = $AutoAdminLogonValue DefaultUsernameName = $DefaultUsernameName DefaultPasswordName = $DefaultPasswordName } } Process { try { Write-EnhancedLog -Message "Setting user account to Auto Login" -Level "INFO" Set-ItemProperty -Path $RegPath -Name $AutoAdminLogonName -Value $AutoAdminLogonValue -Type String -Verbose Set-ItemProperty -Path $RegPath -Name $DefaultUsernameName -Value $TempUser -Type String -Verbose Set-ItemProperty -Path $RegPath -Name $DefaultPasswordName -Value $TempUserPassword -Type String -Verbose } catch { Write-EnhancedLog -Message "An error occurred while setting autologin: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting Set-Autologin function" -Level "INFO" } } # # Example usage with splatting # $SetAutologinParams = @{ # TempUser = 'YourTempUser' # TempUserPassword = 'YourTempUserPassword' # RegPath = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon' # AutoAdminLogonName = 'AutoAdminLogon' # AutoAdminLogonValue = '1' # DefaultUsernameName = 'DefaultUsername' # DefaultPasswordName = 'DefaultPassword' # } # Set-Autologin @SetAutologinParams #EndRegion '.\Public\Set-Autologin.ps1' 68 #Region '.\Public\Set-ODKFMRegistrySettings.ps1' -1 function Set-ODKFMRegistrySettings { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$TenantID, [Parameter(Mandatory = $true)] [string]$RegKeyPath, [Parameter(Mandatory = $true)] [array]$RegistrySettings ) Begin { Write-EnhancedLog -Message "Starting Set-ODKFMRegistrySettings function" -Level "INFO" Log-Params -Params @{ TenantID = $TenantID RegKeyPath = $RegKeyPath RegistrySettings = $RegistrySettings } } Process { try { foreach ($setting in $RegistrySettings) { # Define the parameters to be splatted $SplatParams = @{ RegKeyPath = $RegKeyPath RegValueName = $setting.RegValueName RegValType = $setting.RegValType RegValData = $setting.RegValData } # Call the function with splatted parameters Set-RegistryValue @SplatParams } } catch { Write-EnhancedLog -Message "An error occurred while setting OneDrive KFM registry values: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting Set-ODKFMRegistrySettings function" -Level "INFO" } } # $TenantID = "YourTenantID" # $RegistrySettings = @( # @{ # RegValueName = "AllowTenantList" # RegValType = "STRING" # RegValData = $TenantID # }, # @{ # RegValueName = "SilentAccountConfig" # RegValType = "DWORD" # RegValData = "1" # }, # @{ # RegValueName = "KFMOptInWithWizard" # RegValType = "STRING" # RegValData = $TenantID # }, # @{ # RegValueName = "KFMSilentOptIn" # RegValType = "STRING" # RegValData = $TenantID # }, # @{ # RegValueName = "KFMSilentOptInDesktop" # RegValType = "DWORD" # RegValData = "1" # }, # @{ # RegValueName = "KFMSilentOptInDocuments" # RegValType = "DWORD" # RegValData = "1" # }, # @{ # RegValueName = "KFMSilentOptInPictures" # RegValType = "DWORD" # RegValData = "1" # } # ) # $SetODKFMRegistrySettingsParams = @{ # TenantID = $TenantID # RegKeyPath = "HKLM:\SOFTWARE\Policies\Microsoft\OneDrive" # RegistrySettings = $RegistrySettings # } # Set-ODKFMRegistrySettings @SetODKFMRegistrySettingsParams #optionally you can create an event source here using Create-EventLogSource.ps1 #EndRegion '.\Public\Set-ODKFMRegistrySettings.ps1' 99 #Region '.\Public\Set-RegistryValue.ps1' -1 function Set-RegistryValue { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$RegKeyPath, [Parameter(Mandatory = $true)] [string]$RegValueName, [Parameter(Mandatory = $true)] [string]$RegValType, [Parameter(Mandatory = $true)] [string]$RegValData ) Begin { Write-EnhancedLog -Message "Starting Set-RegistryValue function" -Level "INFO" Log-Params -Params @{ RegKeyPath = $RegKeyPath RegValueName = $RegValueName RegValType = $RegValType RegValData = $RegValData } } Process { try { # Check if registry key exists, create if it does not if (-not (Test-Path -Path $RegKeyPath)) { Write-EnhancedLog -Message "Registry key path does not exist, creating: $RegKeyPath" -Level "INFO" New-Item -Path $RegKeyPath -Force | Out-Null } else { Write-EnhancedLog -Message "Registry key path exists: $RegKeyPath" -Level "INFO" } # Check if registry value exists and its current value $currentValue = $null try { $currentValue = Get-ItemPropertyValue -Path $RegKeyPath -Name $RegValueName } catch { Write-EnhancedLog -Message "Registry value not found, setting new value: $RegValueName" -Level "INFO" New-ItemProperty -Path $RegKeyPath -Name $RegValueName -PropertyType $RegValType -Value $RegValData -Force } # If value exists but data is incorrect, update the value if ($currentValue -ne $RegValData) { Write-EnhancedLog -Message "Updating registry value: $RegValueName with new data: $RegValData" -Level "INFO" Set-ItemProperty -Path $RegKeyPath -Name $RegValueName -Value $RegValData -Force } } catch { Write-EnhancedLog -Message "An error occurred while processing the Set-RegistryValue function: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting Set-RegistryValue function" -Level "INFO" } } # Example usage # Set-RegistryValue -RegKeyPath "HKCU:\Software\MyApp" -RegValueName "MyValue" -RegValType "String" -RegValData "MyData" #EndRegion '.\Public\Set-RegistryValue.ps1' 62 #Region '.\Public\Set-RunOnce.ps1' -1 function Set-RunOnce { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$ScriptPath, [Parameter(Mandatory = $true)] [string]$RunOnceKey, [Parameter(Mandatory = $true)] [string]$PowershellPath, [Parameter(Mandatory = $true)] [string]$ExecutionPolicy, [Parameter(Mandatory = $true)] [string]$RunOnceName ) Begin { Write-EnhancedLog -Message "Starting Set-RunOnce function" -Level "INFO" Log-Params -Params @{ ScriptPath = $ScriptPath RunOnceKey = $RunOnceKey PowershellPath = $PowershellPath ExecutionPolicy = $ExecutionPolicy RunOnceName = $RunOnceName } } Process { try { Write-EnhancedLog -Message "Setting RunOnce script" -Level "INFO" $RunOnceValue = "$PowershellPath -executionPolicy $ExecutionPolicy -File $ScriptPath" Set-ItemProperty -Path $RunOnceKey -Name $RunOnceName -Value $RunOnceValue -Verbose } catch { Write-EnhancedLog -Message "An error occurred while setting RunOnce script: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting Set-RunOnce function" -Level "INFO" } } # # Example usage with splatting # $SetRunOnceParams = @{ # ScriptPath = "C:\YourScriptPath.ps1" # RunOnceKey = "HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce" # PowershellPath = "C:\Windows\System32\WindowsPowerShell\v1.0\Powershell.exe" # ExecutionPolicy = "Unrestricted" # RunOnceName = "NextRun" # } # Set-RunOnce @SetRunOnceParams #EndRegion '.\Public\Set-RunOnce.ps1' 57 #Region '.\Public\Stop-ProcessesUsingOneDriveLib.ps1' -1 function Stop-ProcessesUsingOneDriveLib { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$OneDriveLibPath ) Begin { Write-EnhancedLog -Message "Starting Stop-ProcessesUsingOneDriveLib function" -Level "INFO" Log-Params -Params @{ OneDriveLibPath = $OneDriveLibPath } } Process { try { # Validate before removal $initialProcesses = Validate-OneDriveLibUsage -OneDriveLibPath $OneDriveLibPath if ($initialProcesses.Count -eq 0) { Write-EnhancedLog -Message "No processes found using OneDriveLib.dll before attempting termination." -Level "INFO" } # Terminate processes foreach ($process in $initialProcesses) { Write-EnhancedLog -Message "Found process using OneDriveLib.dll: $($process.ProcessName) (ID: $($process.ProcessId)). Attempting to terminate." -Level "WARNING" Stop-Process -Id $process.ProcessId -Force -ErrorAction Stop } # Validate after removal $remainingProcesses = Validate-OneDriveLibUsage -OneDriveLibPath $OneDriveLibPath if ($remainingProcesses.Count -eq 0) { Write-EnhancedLog -Message "Successfully terminated all processes using OneDriveLib.dll." -Level "INFO" } else { Write-EnhancedLog -Message "Some processes could not be terminated. Manual intervention may be required." -Level "ERROR" foreach ($process in $remainingProcesses) { Write-EnhancedLog -Message "Process still running: $($process.ProcessName) (ID: $($process.ProcessId))." -Level "ERROR" } } } catch { Write-EnhancedLog -Message "An error occurred in Stop-ProcessesUsingOneDriveLib function: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting Stop-ProcessesUsingOneDriveLib function" -Level "INFO" } } # Example usage # Stop-ProcessesUsingOneDriveLib -OneDriveLibPath "C:\ProgramData\AADMigration\Files\OneDriveLib.dll" #EndRegion '.\Public\Stop-ProcessesUsingOneDriveLib.ps1' 52 #Region '.\Public\Suspend-BitLockerWithReboot.ps1' -1 function Suspend-BitLockerWithReboot { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$MountPoint, [Parameter(Mandatory = $true)] [int]$RebootCount ) Begin { Write-EnhancedLog -Message "Starting Suspend-BitLockerWithReboot function" -Level "INFO" Log-Params -Params @{ MountPoint = $MountPoint RebootCount = $RebootCount } } Process { try { Write-EnhancedLog -Message "Suspending BitLocker" -Level "INFO" Suspend-BitLocker -MountPoint $MountPoint -RebootCount $RebootCount -Verbose } catch { Write-EnhancedLog -Message "An error occurred while suspending BitLocker: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting Suspend-BitLockerWithReboot function" -Level "INFO" } } # # Example usage with splatting # $SuspendBitLockerWithRebootParams = @{ # MountPoint = "C:" # RebootCount = 3 # } # Suspend-BitLockerWithReboot @SuspendBitLockerWithRebootParams #EndRegion '.\Public\Suspend-BitLockerWithReboot.ps1' 41 #Region '.\Public\Test-ProvisioningPack.ps1' -1 function Test-ProvisioningPack { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$PPKGName ) Begin { Write-EnhancedLog -Message "Starting Test-ProvisioningPack function" -Level "INFO" Log-Params -Params @{'PPKGName' = $PPKGName} } Process { try { Write-EnhancedLog -Message "Testing to see if provisioning package previously installed" -Level "INFO" $PPKGStatus = Get-ProvisioningPackage | Where-Object { $_.PackagePath -like "*$PPKGName*" } if ($PPKGStatus) { Write-EnhancedLog -Message "Provisioning package previously installed. Removing PPKG." -Level "INFO" $PPKGID = $PPKGStatus.PackageID Remove-ProvisioningPackage -PackageId $PPKGID } } catch { Write-EnhancedLog -Message "An error occurred while testing provisioning pack: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting Test-ProvisioningPack function" -Level "INFO" } } # # Example usage with splatting # $TestProvisioningPackParams = @{ # PPKGName = "YourProvisioningPackName" # } # Test-ProvisioningPack @TestProvisioningPackParams #EndRegion '.\Public\Test-ProvisioningPack.ps1' 39 #Region '.\Public\Validate-OneDriveLibUsage.ps1' -1 function Validate-OneDriveLibUsage { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$OneDriveLibPath ) $processesUsingLib = [System.Collections.Generic.List[PSCustomObject]]::new() try { # Get all processes $processes = Get-Process # Iterate over each process and check if it has loaded OneDriveLib.dll foreach ($process in $processes) { try { $modules = $process.Modules | Where-Object { $_.FileName -eq $OneDriveLibPath } if ($modules) { $processesUsingLib.Add([PSCustomObject]@{ ProcessName = $process.ProcessName ProcessId = $process.Id }) } } catch { # Handle any errors encountered while accessing process modules Write-EnhancedLog -Message "Could not access modules for process: $($process.ProcessName) (ID: $($process.Id)). Error: $($_.Exception.Message)" -Level "WARNING" } } } catch { Write-EnhancedLog -Message "An error occurred in Validate-OneDriveLibUsage function: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } return $processesUsingLib } #EndRegion '.\Public\Validate-OneDriveLibUsage.ps1' 38 |