1

I'm currently trying to run a batch file as a startup script to detect and remove whatever version of office a user has installed and then to install Office 365. I have the install working however, when I attempted to uninstall Office 2013 I received the following error:

Input Error: Can not find script file "C:\Windows\OffScrub_O15msi.vbs"

The Offscrub file is in the same location as the script, is someone able to tell me why it's looking in C:\Windows for it?

Update

Please find my current script which now works for Office 2013, I previously added the line Remove2016Installs $true when using -Command to remove Office 2016, this worked. Since using -File to work around my initial problem I've been unable to get the script to remove Office 2016 and would like some advice on how to do this, I've read that whatever command is after -File needs to be the last which I believe might be why it's failing.

My full script is below:

start "----NOTICE----" cmd.exe /t:ec /Q /k "echo OFFICE 365 IS BEING INSTALLED. THIS WINDOW WILL CLOSE WHEN COMPLETE&&prompt $h"
@echo off
pushd "%~dp0"

powershell.exe -executionpolicy bypass -NoExit -File "Remove-PreviousOfficeInstalls.ps1" 

popd

reg Query "HKLM\Hardware\Description\System\CentralProcessor\0" | find /i "x86" > NUL && set OS=32BIT || set OS=64BIT

if %OS%==32BIT "\\domain\SYSVOL\domain\Policies\{Policy Number}\Machine\Scripts\Startup\setup.exe" /configure "\\domain\SYSVOL\domain\Policies\{Policy Number}\Machine\Scripts\Startup\configuration-Office365-x86.xml"
if %OS%==64BIT "\\domain\SYSVOL\domain\Policies\{Policy Number}\Machine\Scripts\Startup\setup.exe" /configure "\\domain\SYSVOL\domain\Policies\{Policy Number}\Machine\Scripts\Startup\configuration-Office365-x64.xml"
taskkill /IM cmd.exe /FI "WINDOWTITLE EQ ----NOTICE----"
taskkill /IM cmd.exe /FI "WINDOWTITLE EQ Administrator: ----NOTICE----"
echo %date% %time% Setup ended with error code %errorlevel%. >> %LogLocation%\%computername%.txt

Update Finished

There's a line that calls the Powershell script Remove-PreviousOfficeInstalls, this is a file from GitHub that is very popular for the removal of whichever Office version you have installed.

I can run this command if say I copy these files to the desktop and amend the locations in the scripts, I'm not sure what this reference to C:\Windows is though when run from \domain\SYSVOL\domain\Policies{Policy Number}\Machine\Scripts\Startup\?

Seth
  • 1,215
  • 15
  • 35
Admaine
  • 11
  • 4

2 Answers2

0

If you run a default instances of PowerShell it always starts in a certain directory. It depends on how and who it is started by. For instance an administrative PowerShell usually starts in C:\Windows\System32. If you use any paths that are not absolute they're applied relative to this directory.

To work around this you need to change the directory it's using. For instance by using cd to change the directory. My guess would be that your script Remove-PreviousOfficeInstalls.ps1 contains a relative call to the VBS.

An easy fix would be to run a script block instead of a single command and just cd to \\domain\SYSVOL\domain\Policies\'{Policy Number}'\Machine\Scripts\Startup\ prior to running the ps1.

The PowerShell help you can view by following [this] link or running powershell -h has the following information in regards to using the -Command switch.

...

Script blocks must be enclosed in braces ({}). You can specify a script block only when running PowerShell.exe in PowerShell. If you want to use a script block when running from another shell you must use the format:

"& {}"

...

The other important parameter for your use case is -File.

Runs the specified script in the local scope ("dot-sourced"), so that the functions and variables that the script creates are available in the current session. Enter the script file path and any parameters.

...

Your batch contains the following line:

powershell.exe -executionpolicy bypass -Command "\\domain\SYSVOL\domain\Policies\'{Policy Number}'\Machine\Scripts\Startup\Remove-PreviousOfficeInstalls.ps1 -Remove2016Installs $true"

What you do is run a single command to invoke a script with a parameter. The problems is that said script checks its locations based on certain function and with your invocation that location is wrongly detected.

There are multiple ways to fix this. One would be to change the directory before invoking the script. To do this you'd need to use a script block as the parameter for -Command. An example for this would be:

powershell.exe -Command "& {Write-Output 'Hello'; Write-Output 'World';}"

As you can see there are two independent Write-Output commands being run. You'd change this to a cd \\domain\SYSVOL\domain\Policies\'{Policy Number}'\Machine\Scripts\Startup\ and the invocation of your script. As a bonus you wouldn't need to put the whole path in front of the script anymore.

The other option would be to run powershell -File with your current invocation of the script. That should also mean that the script is read from the file and the corresponding parameters are populated accordingly.

If neither of these options work you will have to check what $PSScriptRoot is being populated with and/or what the return of (Get-Item -Path ".\").FullName is as those are the two commands used to determine the location of the script that's being executed. To do this you could use a script block.

Seth
  • 1,215
  • 15
  • 35
  • Hi @Seth, thanks for your response. The link from Github is [link](https://github.com/OfficeDev/Office-IT-Pro-Deployment-Scripts/tree/master/Office-ProPlus-Deployment/Remove-PreviousOfficeInstalls). In terms of editing the batch file that I included in my original post do I simply add your line of code before 'powershell.exe'? Sorry I'm not very experienced in writing scripts. Thanks in advance. – Admaine Oct 11 '18 at 11:03
  • Look for [`GetScriptRoot`](https://github.com/OfficeDev/Office-IT-Pro-Deployment-Scripts/blob/3e03864d3454f438c9714d7231a15cd59a216234/Office-ProPlus-Deployment/Remove-PreviousOfficeInstalls/Remove-PreviousOfficeInstalls.ps1#L1316). Depending on your invocation `$PSScriptRoot` is likely initialized or not. You will have to check that on your own. The `Get-Item` option would likely return the wrong path in your case as the current working directory doesn't change. – Seth Oct 11 '18 at 11:08
  • Check [`powershell -?`](https://technet.microsoft.com/en-us/library/jj553275(v=wps.630).aspx). You need to turn your single command into a script block using the appropriate braces. After that you'd run the change directory command just before your current call for the script. – Seth Oct 11 '18 at 11:11
  • Thanks again @Seth. Apologies for being a complete novice here, are any of the suggestions you mentioned added to the batch file. I've just added cd "\\domain\sysvol\domain\policies\'{policy number}'\Machine\Scripts\Startup"' before the line starting with 'powershell.exe' but unfortunately that didn't work. Any further advice would be great. Thanks – Admaine Oct 11 '18 at 11:25
  • The error I receive is that it doesn't support UNC paths. Thanks – Admaine Oct 11 '18 at 11:33
  • Any more help guys? Thanks in advance – Admaine Oct 11 '18 at 14:45
  • What does your actual edit look like? For instance the cmd `cd` doesn't support UNC paths but the PowerShell `cd` should/does. So the `cd` has to happen within the PowerShell ScriptBlock. It's fine to be a novice. Make sure to read the information available for `-Command` if you run `powershell -h`. – Seth Oct 12 '18 at 05:16
  • Hi @Seth, thanks for your response. So my Powershell script is exactly the same script as seen [link](https://github.com/OfficeDev/Office-IT-Pro-Deployment-Scripts/tree/master/Office-ProPlus-Deployment/Remove-PreviousOfficeInstalls), you're looking at Remove-PreviousOfficeInstalls.ps1. The batch file I'm using is detailed in my original post. All the other files (offscrub_o15.msi/16.msi/setup.exe etc) are all located in the same folder. Each time I run it it prompts me the offscrub_o15.msi for Office 2013 couldn't be located in C:\Windows which is true as it's located in startup scripts folder – Admaine Oct 12 '18 at 07:46
  • `powershell.exe -executionpolicy bypass -Command` you are actually running your own script or rather should if you want to fix your initial call to the script. That parts needs to contain the `cd` and not just the singular command to call the script. – Seth Oct 12 '18 at 08:13
  • Hi @Seth, how do I include that though. Anytime I add the cd it errors that UNC paths aren't supported. Do I need to add it into my PS script before [CmdletBinding(SupportsShouldProcess=$true)] (the first line)? – Admaine Oct 12 '18 at 08:20
  • See the edit for clarification. You could also change the actual ps1 file but as you might be updating it at a later date it's a bad idea. You probably just need to change the `powershell.exe` line in your batch script. – Seth Oct 12 '18 at 08:45
  • 1
    You could use “pushd %~dp0” to mapping the UNC path to Z:\. – Bruce Oct 12 '18 at 09:05
  • 1
    Hi @Seth, thanks again. Ive amended my code to`powershell.exe -executionpolicy bypass -NoExit -Command "& {cd \\domain\SYSVOL\domain\Policies\'{Policy Number}'\Machine\Scripts\Startup\} ".\Remove-PreviousOfficeInstall.ps1"`. This opens cmd with the first couple of lines saying that cmd was started with current path as it's directory. UNC paths aren't supported, defaulting to Windows directory. It then displays the full script and instantly takes me back to the root of the cd folder with the cursor flashing. Nothing seems to run but I'd say a step in the right direction. Is my script OK? – Admaine Oct 12 '18 at 09:17
  • `powershell.exe -executionpolicy bypass -NoExit -Command "& {cd \\domain\SYSVOL\domain\Policies\'{Policy Number}'\Machine\Scripts\Startup\; .\Remove-PreviousOfficeInstall.ps1}"`. You almost got it. The closing bracket was/is in the wrong position. – Seth Oct 12 '18 at 09:59
  • Hi @Seth, just moved the quotation marks but the same response as my last comment. Any other ideas? – Admaine Oct 12 '18 at 10:17
  • The quotation marks (`"`) aren't the (entire) problem. You do have an odd one in there as well. But did you move the bracket (`}`)? Maybe consider updating the initial post. The `-File` option also still exists and what @Bruce offered would mean you wouldn't need to worry about the UNC path. Though it might have other implications. – Seth Oct 12 '18 at 10:25
  • Sorry, just realised I didn't move the } either, having moved that I now receive `The term 'Remove-PreviousOfficeInstall.ps1' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the n ame, or if a path was included, verify that the path is correct and try again. At line:1 char:171. + & {cd \\domain\SYSVOL\domain\Policies\'{Pol No}'\Machine\Scripts\Startup; Remove-PreviousOff iceInstall.ps1 <<<< } + CategoryInfo : ObjectNotFound: (Remove-PreviousOfficeInstall.ps 1:String) [], CommandNotFoundException + FullyQua` – Admaine Oct 12 '18 at 10:25
  • Assuming the error is verbatim you're missing the actual invocation for the script which would either be `.\` or `&`. You're missing the step where you actually tell PowerShell it's a script in the current directory and not a script in the that's in a well known directory. – Seth Oct 12 '18 at 10:29
  • I've just tweaked it having realised a typo (sorry). I now receive the following: `Detecting Office installs... Removing all Office products... '\\domain\SYSVOL\domain\Policies\{Policy Number}\Machine\Scripts\Startup' CMD.EXE was started with the above path as the current directory. UNC paths are not supported. Defaulting to Windows directory.` This then instantly takes me back to the folder location with the cursor flashing. Seems that it's now hitting the powershell command but then nothing happens. – Admaine Oct 12 '18 at 10:31
  • Additionally, if I use the `File` command `powershell.exe -executionpolicy bypass -NoExit -File "& {cd \\domain\SYSVOL\domain\Policies\'{Policy Number}'\Machine\Scripts\Startup; &'.\Remove-PreviousOfficeInstalls.ps1'}"` I receive the error "failed because the file does not have a '.ps1' extension. Specify a valid PowerShell script file name, and then try again" – Admaine Oct 12 '18 at 10:43
  • `-File \\domain\SYSVOL\domain\Policies\'{Policy Number}'\Machine\Scripts\Startup\Remove-PreviousOfficeInstalls.ps1` as file doesn't support a script block. As by the previous comment you can see that the script is actually being launched it also becomes apparent that the script contains further calls to `cmd` as such you'd have to use the suggestion @Bruce to temporarily make the UNC available as drive because not being able to use a UNC path is a limitation of cmd. – Seth Oct 12 '18 at 10:50
  • OK thanks @Bruce @Seth, so will that become `powershell.exe -executionpolicy bypass -NoExit -Command "& {pushd Z:\domain\SYSVOL\domain\Policies\'{Policy Number}'\Machine\Scripts\Startup\%~dp0Remove-PreviousOfficeInstalls.ps1'}"` ? – Admaine Oct 12 '18 at 11:04
  • 1
    Hi guys, I think I've cracked it. The following code runs `@echo off pushd "%~dp0" powershell.exe -executionpolicy bypass -File "Remove-PreviousOfficeInstalls.ps1" >>C:\Test.txt popd` Previously I had to include the command `Remove2016installs $true` even though this appears to be in the Powershell Script but it wouldn't remove or recognise Office 2016 without this command. I'm unable to add this into the script I've included above, is there anywhere else I can add this so that it recognises Office 2016 to? Thanks – Admaine Oct 12 '18 at 13:33
  • Hi @Seth, I was wondering if you were able to shed any light on my comment above, this is the last issue I'm facing. Thanks in advance – Admaine Oct 15 '18 at 08:01
  • @Bruce are you also able to take a look? – Admaine Oct 15 '18 at 08:03
  • Please update your initial question with what your script currently looks likes and why you changed it in the way you did and how your problem changed as a result. – Seth Oct 15 '18 at 09:26
  • Hi @Seth, I've updated my original script now in between **Update** and **Update Finished** above. Thanks in advance – Admaine Oct 15 '18 at 09:46
  • @Seth, any ideas buddy? Apologies for my number of updates I'm just keen to get this working properly. Thanks in advance again – Admaine Oct 15 '18 at 14:03
  • Did you try to add `{-Remove2016Installs $true}` after your ending quotes for your `powershell.exe` line? – Seth Oct 15 '18 at 17:47
  • Hi @Seth, so I've added `@echo off pushd "%~dp0" powershell.exe -executionpolicy bypass -NoExit -File "Remove-PreviousOfficeInstalls.ps1" {-Remove2016Installs $true} >>C:\Test.txt popd` And receive the following error in my test file `Cannot process argument transformation on parameter 'RemoveClickToRunVersions'. Cannot convert value "System.String" to type "System.Boolean", parameters of this type only accept booleans or numbers, use $true, $false, 1 or 0 instead. + CategoryInfo : InvalidData: (:) [Remove-PreviousOfficeInstalls. ps1],` – Admaine Oct 16 '18 at 07:59
  • @Seth. `ParentContainsErrorRecordException + FullyQualifiedErrorId : ParameterArgumentTransformationError,Remove-PreviousOfficeInstalls.ps1` – Admaine Oct 16 '18 at 07:59
  • As suggested [here](https://stackoverflow.com/questions/5079413/how-to-pass-boolean-values-to-a-powershell-script-from-a-command-prompt) it's an error that you would fix by either using `-Command` and/or changing the GitHub script to turn the parameter into a switch parameter rather than a bool. – Seth Oct 17 '18 at 07:43
  • Hi @Seth, if I used `-Command` it will look for the Powershell script in C:\Windows rather than the startup script location so using `-File` works well. If I look inside the Powershell script it already says as the third parameter `[Parameter(ValueFromPipelineByPropertyName=$true)] [bool]$Remove2016Installs = $false,`. Does this not suggest that it's already been converted? What would i need to enter into the Powershell script that's different? – Admaine Oct 17 '18 at 08:17
  • I've just changed that parameter to `$true` and somethings happening. I'll go and run some tests now. – Admaine Oct 17 '18 at 08:20
  • Change the `[bool]` to `[switch]` that way you'd just need to pass the parameter instead of a parameter and a value. Your change, changes the default behavior from false to true. So whenever you run the script (even if you doesn't pass the parameter) it will try to remove 2016. With your current approach you won't be able to change it to false if you need to (as passing false in File doesn't work). As you're a new user check the help section and [what to do if you get an answer](https://stackoverflow.com/help/someone-answers). Pay it forward and try to help people. – Seth Oct 17 '18 at 11:59
  • 1
    @Seth OK so in the Powershell script I've changed it to `[Parameter(ValueFromPipelineByPropertyName=$true)] [switch]$Remove2016Installs = $false,`. Is this correct? Do I now need to amend my batch script to `powershell.exe -executionpolicy bypass -File "Remove-PreviousOfficeInstalls.ps1 {-Remove2016Installs:True}"`? – Admaine Oct 17 '18 at 13:40
  • 1
    Think I've sorted it using `powershell.exe -executionpolicy bypass -File Remove-PreviousOfficeInstalls.ps1 -Remove2016Installs`. The 32 bit process seems to be about 15 minutes quicker than the 64 bit. – Admaine Oct 17 '18 at 15:16
0

thanks for your help regarding this. My resolution was to use the following bat command:

`start "----NOTICE----" cmd.exe /t:ec /Q /k "echo OFFICE 365 IS BEING INSTALLED. THIS WINDOW WILL CLOSE WHEN COMPLETE&&prompt $h"`

@echo off

pushd "%~dp0"

powershell.exe -executionpolicy bypass -File Remove-PreviousOfficeInstalls.ps1 -Remove2016Installs

popd

reg Query "HKLM\Hardware\Description\System\CentralProcessor\0" | find /i "x86" > NUL && set OS=32BIT || set OS=64BIT

if %OS%==32BIT "\\Server\Folder\Folder\setup.exe" /configure "\\Server\Folder\Folder\configuration-Office365-x86.xml" if %OS%==64BIT "\\Server\Folder\Folder\setup.exe" /configure "\\Server\Folder\Folder\configuration-Office365-x64.xml" taskkill /IM cmd.exe /FI "WINDOWTITLE EQ ----NOTICE----" taskkill /IM cmd.exe /FI "WINDOWTITLE EQ Administrator: ----NOTICE----" echo %date% %time% Setup ended with error code %errorlevel%. >> %LogLocation%\%computername%.txt

I had to amend the Remove-PreviousOfficeInstalls powershell script to include the switch command:

[Parameter(ValueFromPipelineByPropertyName=$true)] [switch]$Remove2016Installs = $false,

This then did exactly what I was after, it detected the current version of Office, removed it and installed the correct bit version of Office 365 for that PC\Laptop.

Thanks for all your help

Admaine
  • 11
  • 4