0

I have written a batch file to uninstall a faulty WiFi driver (Intel ProSet Wireless) and set up the appropriate wireless profile on a laptop. This script is intended to be run remotely through Symantec Management Agent.

The code starts by running a group policy update to pull down appropriate network certificates from the server. Then the code checks to see if the WiFi driver is installed. If it is, the script uninstalls it. Afterwards, in either case, it will wipe the current wireless profiles and call another batch file to install the appropriate wireless profile.

My issue is, when I run the script, the console will report "The system cannot open the device or file specified." after the software is uninstalled and it will terminate. The IF EXIST statement checks to see if one of the software files is there.

Typically, I can just run the same script a second time, and the IF EXIST case will not be met, so the rest of the batch file will work properly.

I am attaching my code below -- am I using IF EXIST correctly?

gpupdate /force
IF EXIST "C:\ProgramData\Package Cache\{552523b2-40ad-46b3-94f6-2b99d0860d5c}\setup.exe" (

cd "C:\ProgramData\Package Cache\{552523b2-40ad-46b3-94f6-2b99d0860d5c}\"
start /wait setup.exe /uninstall

) 

TIMEOUT /T 3 /nobreak >nul
netsh wlan delete profile name=*
cd "C:\Wireless_Settings\"
Mobile_Devices_profile.bat

I have researched other posts, and I do believe I am using the condition correctly. I don't see any other post that matches my case. It always correctly checks to see if the condition is met, however I don't understand why the program terminates after the software is uninstalled. All that I believe should happen is the case is no longer met, so the script continues on.

Squashman
  • 13,649
  • 5
  • 27
  • 36
Justin
  • 1
  • 1
    *"The system cannot open the device or file specified."* error seems to be related to `.MSI`/`setup` installation process (google suggests e.g. pause antivirus temporarily etc.) https://stackoverflow.com/questions/32727996 – JosefZ Mar 01 '18 at 20:24
  • I agree with @JosefZ, I don't get that message when I check for the existence of files in those folder paths. – Squashman Mar 01 '18 at 20:28
  • 1
    The package cache directory is usually also deleted during uninstall of a package. Therefore it is not good to make this directory the active directory. I suggest to change the entire __IF__ condition to: `if exist "C:\ProgramData\Package Cache\{552523b2-40ad-46b3-94f6-2b99d0860d5c}\setup.exe" start "" /wait /D%SystemRoot%\System32 "C:\ProgramData\Package Cache\{552523b2-40ad-46b3-94f6-2b99d0860d5c}\setup.exe" /uninstall`. – Mofi Mar 01 '18 at 21:49

2 Answers2

0

Possible solution : (your if statement appears to be correct)

Insert a pushd statement before the cd and a popd after the start.

This will ensure you return to your original directory after the if statement invokes setup.exe


IF EXIST "C:\ProgramData\Package Cache\{552523b2-40ad-46b3-94f6-2b99d0860d5c}\setup.exe" (
PUSHD
cd "C:\ProgramData\Package Cache\{552523b2-40ad-46b3-94f6-2b99d0860d5c}\"
start /wait setup.exe /uninstall
POPD
) 

If it works, fine and good. If it doesn't, It's easy to undo.

Sure - in theory, you could change the cd to a PUSHD instead. There are many paths.


IF EXIST "C:\ProgramData\Package Cache\{552523b2-40ad-46b3-94f6-2b99d0860d5c}\setup.exe" (
PUSHD "C:\ProgramData\Package Cache\{552523b2-40ad-46b3-94f6-2b99d0860d5c}\"
start /wait setup.exe /uninstall
POPD
) 

This should work.

Now that's interesting. I'm sure I've use pushd without arguments before. The documentation reads

Stores the current directory for use by the POPD command, then changes to the specified directory.

PUSHD [path | ..]

which is not explicit when the option argument is missing.

I've also noticed that a dir list on my batch-development directory now lists a unicode-named file with spaces between the squares whereas it used to not contain those spaces. Maybe something has been silently changed... cmd version is dated 20170929

Magoo
  • 77,302
  • 8
  • 62
  • 84
  • `pushd` statement **instead of** the `cd`? I'd suggest `CALL Mobile_Devices_profile.bat&PAUSE` – JosefZ Mar 01 '18 at 19:47
  • @JosefZ No. `pushd` /cd .../start.../ `popd` all on separate lines because it's easier to reverse that way. – Magoo Mar 01 '18 at 19:48
  • @Magoo I was thinking the same thing as JosefZ. How would I invoke pushd and cd on separate lines like that? Doesn't pushd more or less perform the same function as cd? Also, I did try using it as a replacement and received the same error. The error occurs at the end of the IF statement. TIMEOUT .... is never reached – Justin Mar 01 '18 at 19:59
  • **Why** `PUSHD` without any parameter? If neither drive nor path are specified `PUSHD` will **just display** a list of previous pathnames… – JosefZ Mar 01 '18 at 20:18
  • `pushd .` works. All it does is remember the current directory. I wouldn't use it that way. Moving the current working directory in your script is usually a bad idea. It does not compose well in the face of script failures, especially pushd/popd, they are convenient only for interactive use. Use fully qualified or relative paths and use `start /d path ...`. – jwdonahue Mar 01 '18 at 20:35
  • Actually, in this case, you probably don't want to set the working directory at all. Use `call C:\ProgramData\Package Cache\{552523b2-40ad-46b3-94f6-2b99d0860d5c}\setup.exe /uninstall` instead. – jwdonahue Mar 01 '18 at 20:40
0

Setup.exe is trying to remove the directory from the Package Cache which happens to be your current working directory. Not a good way for a script to live.

@setlocal ENABLEEXTENSIONS
@rem @set prompt=$G

@set "_setupExe=C:\ProgramData\Package Cache\{552523b2-40ad-46b3-94f6-2b99d0860d5c}\setup.exe"

@gpupdate /force
@if exist "%_setupExe%" call %_setupExe% /uninstall

@TIMEOUT /T 3 /nobreak >nul
@netsh wlan delete profile name=*
@cd "C:\Wireless_Settings\"
@Mobile_Devices_profile.bat

I would add that debugging your script was complicated by the fact that you had a multi-line code block. You should avoid those at all costs. It's better to call a subroutine if you can fit it all on a single line.

jwdonahue
  • 6,199
  • 2
  • 21
  • 43