0

I'm trying to make a powershell script to uninstall Onedrive from users computers by running Invoke-Command -computername computer1 -filepath script.ps1 but i keep getting issues with the last step. The first function "doUninstall" works just fine, it runs it and so on. But the second one "douninstall2" doesnt work, it cant run the file Anyone have any ideas what im doing wrong and how to fix this?

When i try running it using Start-Process -filepath $UninstallCommand -ArgumentList "$EXEArgumente" -Wait I can see the process starting on the target computer but it closes immediately

C:\Users\myuser\AppData\Local\Microsoft\OneDrive\23.002.0102.0004_5\OneDriveSetup.exe  /uninstall
DEBUG:   78+    >>>> Write-Output "Uninstalling OneDrive found in Uninstall registry key"
Uninstalling OneDrive found in Uninstall registry key
DEBUG:   79+    >>>> $proc = Start-Process "$UninstallString" -PassThru
DEBUG:   83+   >>>> Write-Output "Uninstall failed with exception $_.exception.message"
Uninstall failed with exception This command cannot be run due to the error: The system cannot find the file specified..exception.message


#Requires -RunAsAdministrator
Set-PSDebug -Trace 2
function doUninstall($check) {
    if (Test-Path $check) {
        Write-Output "Uninstalling OneDrive found in $check"
        $proc = Start-Process $check "/uninstall" -PassThru
        $proc.WaitForExit()
    }
}
function douninstall2  {
    if (Test-Path $UninstallString) {
    $UninstallString
        Write-Output "Uninstalling OneDrive found in Uninstall registry key"
        $proc = Start-Process "$UninstallString" -PassThru
        $proc.WaitForExit()
    }
        else { 
    write-output "File not found"
    }
}

function unstring {
$PatternSID = 'S-1-5-21-\d+-\d+\-\d+\-\d+$'
$username = Read-Host "Enter User ID: "
$ApplicationName = "Microsoft Onedrive"
# Get Username, SID, and location of ntuser.dat for all users
$ProfileList = gp 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\*' | Where-Object {$_.PSChildName -match $PatternSID} | 
    Select  @{name="SID";expression={$_.PSChildName}}, 
            @{name="UserHive";expression={"$($_.ProfileImagePath)\ntuser.dat"}}, 
            @{name="$username";expression={$_.ProfileImagePath -replace '^(.*[\\\/])', ''}}
 
# Get all user SIDs found in HKEY_USERS (ntuder.dat files that are loaded)
$LoadedHives = gci Registry::HKEY_USERS | ? {$_.PSChildname -match $PatternSID} | Select @{name="SID";expression={$_.PSChildName}}
 
# Get all users that are not currently logged
$UnloadedHives = Compare-Object $ProfileList.SID $LoadedHives.SID | Select @{name="SID";expression={$_.InputObject}}, UserHive, Username
 
# Loop through each profile on the machine
Foreach ($item in $ProfileList) {
    # Load User ntuser.dat if it's not already loaded
    IF ($item.SID -in $UnloadedHives.SID) {
        reg load HKU\$($Item.SID) $($Item.UserHive) | Out-Null
    }
 
    #####################################################################
    # This is where you can read/modify a users portion of the registry 
 
    # This example lists the Uninstall keys for each user registry hive
    "{0}" -f $($item.Username) | Write-Output
    $Global:Selection = (Get-ChildItem -Path registry::HKEY_USERS\$($Item.SID)\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | ForEach-Object { Get-ItemProperty $_.PSPath } | Where-Object { $_.DisplayName -match "$ApplicationName" } | Select-Object Publisher,DisplayName,Version,UninstallString)
    #$Selection2 = (Get-ChildItem -Path registry::HKEY_USERS\$($Item.SID)\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | ForEach-Object { Get-ItemProperty $_.PSPath } | Where-Object { $_.DisplayName -match "$ApplicationName" } | Select-Object Publisher,DisplayName,Version,UninstallString)
    
    #####################################################################
$Selection | ForEach-Object {
    $Global:UninstallString = $_.UninstallString
   
   
}
}

    # Unload ntuser.dat        
    IF ($item.SID -in $UnloadedHives.SID) {
        ### Garbage collection and closing of ntuser.dat ###
        [gc]::Collect()
        reg unload HKU\$($Item.SID) | Out-Null
    }

}

try {
    $check1 = "$ENV:SystemRoot\System32\OneDriveSetup.exe"
    $check2 = "$ENV:SystemRoot\SysWOW64\OneDriveSetup.exe"
    $check3 = "$ENV:ProgramFiles\Microsoft Office\root\Integration\Addons\OneDriveSetup.exe"
    $check4 = "${ENV:ProgramFiles(x86)}\Microsoft Office\root\Integration\Addons\OneDriveSetup.exe"

    Write-Output "Stopping OneDrive processes..."
    Stop-Process -Name OneDrive* -Force -ErrorAction SilentlyContinue

    # Uninstall from common locations
    doUninstall($check1)
    doUninstall($check2)
    doUninstall($check3)
    doUninstall($check4)

    # Uninstall from Uninstall registry key UninstallString
    unstring
    douninstall2

}
catch {
    Write-Output "Uninstall failed with exception $_.exception.message"
    exit 1
}

I've tried multiple solutions, like adding "" around the path, adding in invoke-command inside the code but nothing works for me.

uninstall-package wont work for me here.

Adde
  • 1
  • 1
  • Where is variable $UninstallString defined? – jdweng Jan 30 '23 at 14:35
  • MIne is this `C:\Program Files\Microsoft OneDrive\23.007.0109.0004\OneDriveSetup.exe /uninstall /allusers`. You'd have to separate the command from the arguments. – js2010 Jan 30 '23 at 14:42
  • Try something like `$s = -split $UninstallString; & $s[0..2] $s[3..4]` – js2010 Jan 30 '23 at 20:34
  • The uninstallstring is defined under function unstring. – Adde Jan 31 '23 at 07:40
  • Hmm how/where should i add that js2010? – Adde Jan 31 '23 at 07:42
  • The earlier command $proc = Start-Process $check "/uninstall" -PassThru works fine, is that because /uninstall has the "" ? – Adde Jan 31 '23 at 07:43
  • Added $ExpandedUninstallString = $UninstallString -split "/" $Global:UninstallCommand = $ExpandedUninstallString[0] $EXEArgumente = "/uninstall" Start-Process -filepath $UninstallCommand -ArgumentList "$EXEArgumente" but still wont work – Adde Jan 31 '23 at 08:02

0 Answers0