I got it into my head earlier this evening that maybe I couldn’t reach my files that should be registered in the PATH variable because it had been truncated, after all when I ran
ECHO %PATH%
I did get a truncated text. However that is probably just due to the output buffer being capped looking at this post about maximum length of environment variables.
By this point however, I had already begun building a script to try and shorten down my PATH variable, I mean, who would ever do that manually?……. I mean, who wouldn’t spend two hours writing a script to do it?……. I mean, yea, you could’ve used a regex and split it, done a 5 second ocular inspection, decided that it couldn’t be improved and left it at that but that wouldn’t be fun would it?……. ok. I got carried away.
So, anyway, I did some research, a lot of trial and error and the script I came up with not only removes any multiples of registered directories and missing ones in the PATH variable but also showcases some cool useful stuff you can do with a VBScript or command prompt, such as:
- Restarting current command prompt
- Which is good for reloading environment variables
- Simply:
START cmd /SEPARATE & EXIT
- Running an elevated command from within the script
- Grabbing output from another script
- Changing environment variables from within a script
- Checking whether or not you’re running in elevated mode
So the script looks like this and is ready to run with cscript or wscript from elevated or non elevated mode, the one thing I didn’t bother fixing in the end was to output the text from the elevated process to the first process if it’s restarted as elevated:
Dim application : Set application = CreateObject("Shell.Application") Dim shell : Set shell = CreateObject("WScript.Shell") Dim filesystem : Set filesystem = CreateObject("Scripting.FileSystemObject") Dim winMgmt : Set winMgmt = GetObject("WinMGMTS://./Root/CIMv2") Function Elevated() Dim waitOnReturn : waitOnReturn = true Dim windowStyle : windowStyle = 1 Dim execResult : Set execResult = shell.Exec("%comspec% /c whoami /groups | find ""S-1-16-12288""") Do While execResult.Status = 0 WScript.Sleep 100 Loop Dim output : output = execResult.StdOut.ReadAll If InStr(output, "S-1-16-12288") Then Elevated = true Else Elevated = false End If End Function If Not Elevated() Then WScript.Echo "Not running as elevated user, will restart with UAC control" WScript.Echo "Will now run as elevated in another window, to get effects afterwards this console will need to be restarted." WScript.Echo "To restart a command prompt use: START cmd /SEPARATE & EXIT" application.ShellExecute "cscript.exe", WScript.ScriptFullName, "", "runas", 1 WScript.Quit End If Function TrimTrailingSlash(path) If Right(path, 1) = Chr(92) Then ' Chr(92) = , used Chr to not mess up syntax highlighting TrimTrailingSlash = Left(path, Len(path) - 1) Else TrimTrailingSlash = path End If End Function Function InPath(totalPath, subPath) Dim caseInsensitive : caseInsensitive = 1 InPath = InStr(1, totalPath, subPath & ";", caseInsensitive) End Function Function InPathExpanded(totalPath, subPath) InPathExpanded = InPath(shell.ExpandEnvironmentStrings(totalPath), shell.ExpandEnvironmentStrings(subPath)) End Function Dim sysEnv : Set sysEnv = shell.Environment("SYSTEM") Dim pathEntries : pathEntries = Split(sysEnv("PATH"), ";") Dim path, newPath, folderPath, itemsSaved newPath = "" itemsSaved = 0 For Each path in pathEntries path = TrimTrailingSlash(path) folderPath = shell.ExpandEnvironmentStrings(path) If Not filesystem.FolderExists(folderPath) Then WScript.Echo "Folder missing, removing from path: " & path ElseIf InPath(newPath, path) Then WScript.Echo "Folder exists in path multiple times, skipping: " & path ElseIf InPathExpanded(newPath, path) Then WScript.Echo "Folder exists in expanded path (no %...%) multiple times, skipping: " & folderPath Else newPath = newPath & path & ";" itemsSaved = itemsSaved + 1 End If Next WScript.Echo "" WScript.Echo "Output path = " & newPath WScript.Echo "" Dim optimized : optimized = UBound(pathEntries) - itemsSaved + 1 WScript.Echo "Saving " & itemsSaved & " items, optimized " & optimized & " items." sysEnv("PATH") = newPath WScript.Echo "All done! If running in a command prompt you will need to restart it for effects to kick in." WScript.Echo "To restart a command prompt use: START cmd /SEPARATE & EXIT" WScript.Sleep 2000
If nothing else, I hope it could at least serve as an example of some scripting techniques.
Edit (5 minutes later):
Forgot to credit the sources from which most of the above was combined, fixing the path here and running elevated here.