impact/Install-ImpactOneDrive.ps1

function Install-ImpactOneDrive {
#Module name: O4BClientAutoConfig
#Author: Jos Lieben (OGD)
#Author Company: OGD (http://www.ogd.nl)
#Author Blog: http://www.lieben.nu
#Date: 12-02-2018
#Purpose: Configure Onedrive for Business (Onedrive.exe) to silently link to the user's business tenant, and optionally redirect known folders to desired subfolders
#Requirements: Windows 10, Powershell script should run as an Admin if O4B wasn't installed yet

$logFile = Join-Path $Env:TEMP -ChildPath "OnedriveAutoConfig.log"
$xmlDownloadURL = "https://g.live.com/1rewlive5skydrive/ODSUInsider"
$temporaryInstallerPath = "C:\Users\cpurcell\AppData\Local\Temp\OnedriveInstaller.EXE"
$minimumOfflineVersionRequired = "17"
$onedriveRootKey = "HKCU:\Software\Microsoft\OneDrive\Accounts\Business"
$desiredBootScriptFolder = "C:\ProgramData\Lieben.nu"
$desiredBootScriptPath = "C:\ProgramData\Lieben.nu\O4BClientAutoConfig.ps1"
Start-Transcript -Path $logFile

#ENSURE CONFIG REGISTRY KEYS ARE CREATED
try{
    Write-Output "Adding registry keys for Onedrive"
    $res = New-Item -Path "HKCU:\Software\Microsoft\Onedrive" -Confirm:$False -ErrorAction SilentlyContinue
    $res = New-ItemProperty -Path "HKCU:\Software\Microsoft\Onedrive" -Name DefaultToBusinessFRE -Value 1 -PropertyType DWORD -Force -ErrorAction Stop
    $res = New-ItemProperty -Path "HKCU:\Software\Microsoft\Onedrive" -Name DisablePersonalSync -Value 1 -PropertyType DWORD -Force -ErrorAction Stop
    $res = New-ItemProperty -Path "HKCU:\Software\Microsoft\Onedrive" -Name EnableEnterpriseTier -Value 1 -PropertyType DWORD -Force -ErrorAction Stop
    $res = New-ItemProperty -Path "HKCU:\Software\Microsoft\Onedrive" -Name EnableADAL -Value 1 -PropertyType DWORD -Force -ErrorAction Stop
    Write-Output "Registry keys for Onedrive added"
}catch{
    Write-Error "Failed to add Onedrive registry keys, installation may not be consistent" -ErrorAction Continue
    Write-Error $_ -ErrorAction Continue
}

function returnEnclosedValue{
    Param(
        [Parameter(Mandatory = $True)]$sourceString,
        [Parameter(Mandatory = $True)]$searchString
    )
    try{
        $endString = "`""
        $start = $searchString
        $startLoc = $sourceString.IndexOf($start)+$start.Length
        if($startLoc -eq $start.Length-1){
            Throw "Not Found"
        }
        $searchLength = $sourceString.IndexOf($endString,$startLoc)-$startLoc
        if($searchLength -eq $startLoc-1){
            Throw "Not Found"
        }
        return($sourceString.Substring($startLoc,$searchLength))
    }catch{Throw}
}

function runProcess ($cmd, $params, $windowStyle=1) {
    $p = new-object System.Diagnostics.Process
    $p.StartInfo = new-object System.Diagnostics.ProcessStartInfo
    $exitcode = $false
    $p.StartInfo.FileName = $cmd
    $p.StartInfo.Arguments = $params
    $p.StartInfo.UseShellExecute = $False
    $p.StartInfo.RedirectStandardError = $True
    $p.StartInfo.RedirectStandardOutput = $True
    $p.StartInfo.WindowStyle = $windowStyle; #1 = hidden, 2 =maximized, 3=minimized, 4=normal
    $null = $p.Start()
    $output = $p.StandardOutput.ReadToEnd()
    $exitcode = $p.ExitCode
    $p.Dispose()
    $exitcode
    $output
}

$isOnedriveUpToDate = $False
#GET ONLINE VERSION INFO
try{
    $xmlInfo = Invoke-WebRequest -UseBasicParsing -Uri $xmlDownloadURL -Method GET
    $version = returnEnclosedValue -sourceString $xmlInfo.Content -searchString "currentversion=`""
    $downloadURL = returnEnclosedValue -sourceString $xmlInfo.Content -searchString "url=`""
    write-output "Microsoft's XML shows the latest Onedrive version is $version and can be downloaded from $downloadURL"
}catch{
    write-error "Failed to download / read version info for Onedrive from $xmlDownloadURL" -ErrorAction Continue
    write-error $_ -ErrorAction Continue
}

#GET LOCAL INSTALL STATUS AND VERSION
try{
    $installedVersion = (Get-ItemProperty -Path "HKCU:\Software\Microsoft\OneDrive" -Name "Version" -ErrorAction Stop).Version
    $installedVersionPath = (Get-ItemProperty -Path "HKCU:\Software\Microsoft\OneDrive" -Name "OneDriveTrigger" -ErrorAction Stop).OneDriveTrigger
    Write-Output "Detected $installedVersion in registry"
    if($installedVersion -le $minimumOfflineVersionRequired -or ($version -and $version -gt $installedVersion)){
        Write-Output "Onedrive is not up to date!"
    }else{
        $isOnedriveUpToDate = $True
        Write-Output "Installed version of Onedrive is newer or the same as advertised version"
    }
}catch{
    write-error "Failed to read Onedrive version information from the registry, assuming Onedrive is not installed" -ErrorAction Continue
    write-error $_ -ErrorAction Continue
}

#DOWNLOAD ONEDRIVE INSTALLER AND RUN IT
try{
    if(!$isOnedriveUpToDate -and $downloadURL){
        Write-Output "downloading from download URL: $downloadURL"
        Invoke-WebRequest -UseBasicParsing -Uri $downloadURL -Method GET -OutFile $temporaryInstallerPath
        Write-Output "downloaded finished from download URL: $downloadURL"
        if([System.IO.File]::Exists($temporaryInstallerPath)){
            Write-Output "Starting client installer"
            Sleep -s 5 #let A/V scan the file so it isn't locked
            #first kill existing instances
            get-process | where {$_.ProcessName -like "onedrive*"} | Stop-Process -Force -Confirm:$False
            Sleep -s 5
            runProcess $temporaryInstallerPath "/silent"
            Sleep -s 5
            Write-Output "Install finished"
        }
        $installedVersionPath = (Get-ItemProperty -Path "HKCU:\Software\Microsoft\OneDrive" -Name "OneDriveTrigger" -ErrorAction Stop).OneDriveTrigger
    }
}catch{
    Write-Error "Failed to download or install from $downloadURL" -ErrorAction Continue
    Write-Error $_ -ErrorAction Continue
}

#WAIT FOR CLIENT CONFIGURATION AND REDETERMINE PATH
$maxWaitTime = 600
$waited = 0
Write-Output "Checking existence of client folder"
:detectO4B while($true){
    if($waited -gt $maxWaitTime){
        Write-Output "Waited too long for client folder to appear. Running auto updater, then exiting"
        $updaterPath = Join-Path $Env:LOCALAPPDATA -ChildPath "Microsoft\OneDrive\OneDriveStandaloneUpdater.exe"
        runProcess $updaterPath
        Sleep -s 60
        runProcess $installedVersionPath
        Sleep -s 60
    }

    $checks = 5
    for($i=1;$i -le $checks;$i++){
        #check if a root path for the key exists
        $subPath = "$($onedriveRootKey)$($i)"
        if(Test-Path $subPath){
            $detectedTenant = (Get-ItemProperty -Path "$($subPath)\" -Name "ConfiguredTenantId" -ErrorAction SilentlyContinue).ConfiguredTenantId
            #we've found a business key with the correct TenantID, Onedrive has been started, check for the folder path
            $detectedFolderPath = (Get-ItemProperty -Path "$($subPath)\" -Name "UserFolder" -ErrorAction SilentlyContinue).UserFolder
            if($detectedFolderPath -and [System.IO.Directory]::Exists($detectedFolderPath)){
                Write-Output "detected user folder at $detectedFolderPath, linked to tenant $detectedTenant"
                break detectO4B
            }
        }
    }
    if($waited -gt $maxWaitTime){
        break
    }
    Write-Output "failed to detect user folder! Sleeping for 30 seconds"
    Sleep -Seconds 30
    $waited+=30   
     
    #GET LOCAL INSTALL PATH
    try{
        $installedVersionPath = (Get-ItemProperty -Path "HKCU:\Software\Microsoft\OneDrive" -Name "OneDriveTrigger" -ErrorAction Stop).OneDriveTrigger
        Write-Output "Detected Onedrive at $installedVersionPath"
    }catch{
        write-error "Failed to read Onedrive version information from the registry" -ErrorAction Continue
        $installedVersionPath = Join-Path $Env:LOCALAPPDATA -ChildPath "Microsoft\OneDrive\OneDrive.exe"
        Write-output "Will use auto-guessed value of $installedVersionPath"
    }

    #RUN THE LOCAL CLIENT IF ALREADY INSTALLED
    Write-Output "Starting client..."
    & $installedVersionPath
}


Stop-Transcript
Exit

}