# AD FS Backup and Restore
# Reference documentation: https://learn.microsoft.com/en-us/windows-server/identity/ad-fs/operations/ad-fs-rapid-restore-tool

# Set Variables
$filePassword="password"
$adfsToolDownload="https://download.microsoft.com/download/6/8/A/68AF3CD3-1337-4389-967C-A6751182F286/ADFSRapidRecreationTool.msi"
$downloadedFile="C:\Temp\ADFSRapidRecreationTool.msi"
$adfsBackupFolder="C:\Backup\ADFS"

# This function installs the MSI onto a the local system and output a log
function installMsi{
	param($msiFile)
	$dateStamp = get-date -Format yyyyMMddTHHmm
	$parentFolder=split-path $msiFile -parent
	$fileName=split-path $msiFile -leaf
	$logFile = "$parentFolder\$fileName-$dateStamp.log"
	Start-Process msiexec.exe -Wait -ArgumentList "/I $msiFile /qn /norestart /L*V $logFile"
}

# This function download a file via HTTPS to a specific local path
function downloadFile{
	param(
		[Parameter(Mandatory=$true)][String]$sourceUrl,
		[Parameter(Mandatory=$true)][String]$destinationFile
		)
	<# Pre-emptively resolve this error
	Exception calling "DownloadFile" with "2" argument(s): "An exception occurred during a WebClient request."
	At line:1 char:1
	+ (New-Object System.Net.WebClient).DownloadFile(, ...
	+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		+ CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
		+ FullyQualifiedErrorId : WebException
	#>
	$parentDirectory=split-path $destinationFile -Parent
	if (!(Test-Path $parentDirectory -ea SilentlyContinue)){New-Item -ItemType Directory -Force -Path $parentDirectory}
	(New-Object System.Net.WebClient).DownloadFile($adfsToolDownload, $downloadedFile)
}

function installAdfsTool{
    $adfsToolExists=test-path 'C:\Program Files (x86)\ADFS Rapid Recreation Tool\ADFSRapidRecreationTool.dll'
    if (!($adfsToolExists)){
        write-host "AD FS Tool doesn't exist in this system. Installing..."
        downloadFile -sourceUrl $adfsToolDownload -destinationFile $downloadedFile
        installMsi -msiFile '$downloadedFile'
        }else{
            write-host "AD FS Tool already exists"
            }
}

# Create a backup of AD FS
function backupAdfs{
    installAdfsTool;
    import-module 'C:\Program Files (x86)\ADFS Rapid Recreation Tool\ADFSRapidRecreationTool.dll'
    if (!(Test-Path $adfsBackupFolder -ea SilentlyContinue)){New-Item -ItemType Directory -Force -Path $adfsBackupFolder | Out-null}
    Try{
        Backup-ADFS -StorageType "FileSystem" -StoragePath $adfsBackupFolder -EncryptionPassword $filePassword -BackupComment "ADFS Backup $(get-date)" -BackupDKM;
        write-host "AD FS has been backed up at this location $adfsBackupFolder";
        }catch{
            write-host $Error
            write-host "AD FS backup failed."
            break;
            }
}

function connectMsol{
    $connected=Get-MsolDomain -ErrorAction SilentlyContinue
    if($connected){
        "This session is currently connected to MsolService as follows:`r`n$($connected|Out-String)"
        }else{
            Connect-MsolService;
            "This session is now connected to MsolService as follows:`r`n$($connected|Out-String)"
            }
}

function backupAdfsToXml{
    connectMsol;
    if (!(Test-Path $adfsBackupFolder -ea SilentlyContinue)){New-Item -ItemType Directory -Force -Path $adfsBackupFolder | Out-null}
    (Get-AdfsRelyingPartyTrust -Name "Microsoft Office 365 Identity Platform") | Export-CliXML "$adfsBackupFolder\O365-RelyingPartyTrust.xml"
}

# Restore AD FS
# Before using the AD FS Rapid Recovery Tool, ensure that the server is joined to the domain prior to restoring the backup.
function restoreAdfs{
    Restore-ADFS -StorageType "FileSystem" -StoragePath $adfsBackupFolder -DecryptionPassword $filePassword -RestoreDKM
}

write-host "Functions to trigger: backupAdfsToXml | backupAdfs | restoreAdfs"