Files
windows-scripts/ChangeShortcutPath.vbs
2023-12-05 19:39:38 -06:00

455 lines
14 KiB
Plaintext
Executable File

'~~Author~~. Rob Dunn
'
'~~Blatently borrowed a little bit of code from~~. Jim de Graff
'
'~~Script_Type~~. vbscript
'
'~~Sub_Type~~. SystemAdministration
'
'~~Keywords~~. change shortcuts, string, migration,
' mapped drive, new server, LNK, target path
'
'~~Comment~~.
'This script searches the given folder (and sub-folders) for shortcuts
' that contains a particular string (i.e. "c:\temp\shortcut_target.exe"
' first it will prompt you to type the string you wish to replace,
' after which, it prompts for the new string. Finally, it will ask
' you for the root folder which you would like to begin the search
' (and replace). If you run in verbose mode, you will be prompted
' to say 'yes' for each shortcut you'd like to change. After it's
' finished, it will present you with an HTM of the changes that
' were made.
'
'This script only works with single instances of a string - if there are
' more than one instance, the script will change the first instance.
'
'A few lines below are variables that you can set to modify the behavior
' of the script. In this form, Silent = 0 (off), which will prompt you
' with each shortcut it finds that meet the criteria specified in the
' initial input boxes. As it finds matching shortcuts, it will prompt
' you to type 'yes' to change the shortcuts.
'
'I just changed a server name at a location, and all the users had a
' TON of shortcuts pointing to the old server name, so I put this
' together to save me time, and it worked great!
'
'At the very end, it will open up an HTM file with the results of the
' shortcuts that it finds (and highlight which ones are updated)
'
'Per Jim de Graff: "also demonstrates how to traverse a directory tree"
' using recursion."'
'~~Script~~.
Dim Silent, CurTime, sIsDrive
Dim newlink, oldlink, oldfull, fullname, oldfile, bgcolor
Dim CheckFolder, RootFolder
Dim w, ws
const ForReading = 1
const ForWriting = 2
const ForAppending = 8
'On Error Resume Next
'Find current time that the script runs
set wso = CreateObject("Wscript.Shell")
set fso = CreateObject("Scripting.FileSystemObject")
'pull the system's process variables (we'll be using TEMP
' for the output file and WINDIR to figure out the default
' location of user's desktop folder - whether 9x or NT/2k/XP)
Set WshSysEnv = wso.Environment("PROCESS")
'pull the system's profile environment variable
userprofile = wso.ExpandEnvironmentStrings("%userprofile%")
'set your variables here
'silent = 0/1/2
' 0 - verbose
' 1 - turns off verification prompts
' 2 - turns off verification and initial config prompts
'ChangePathFrom = string you wish to replace
'ChangePathTo = string you wish to change ChangePathFrom to
' above server vars are needed only for when silent = 2
'ouputfile = location of output filename, you can use a string in
' place of all the code after the equal sign (i.e.
' outputfile = "x:\temp," etc.)
'curtime = finds time of execution of script
'RootFolder = The folder that you wish to search (silent mode only)
'--------------------------------------------------------------------
' set your variables below...
'--------------------------------------------------------------------
Silent = 1
ChangePathFrom = "\\test1" 'string to search for
ChangePathTo = "\\test2" 'string to replace with
OutputFile = WshSysEnv("TEMP") & "\" & "migrate_shortcuts_log.htm"
RootFolder = "c:\shortcut"
'--------------------------------------------------------------------
CurTime = Now
OSType = WshSysEnv("OS")
WinDirectory = WshSysEnv("WINDIR")
If Silent > 0 Then
CheckFolder = RootFolder
Else
End If
If CheckFolder = "" Then
If OSType <> "Windows_NT" Then
'Windows 9x/Me desktop folder
CheckFolder = Windirectory & "\desktop"
Else
'Windows NT/2k/XP desktop folder
CheckFolder = userprofile & "\desktop"
End If
End If
'check to see if ouputfile exists or not, deletes it if it does
If CheckFileExists(OutputFile) Then
Set oldfile = fso.GetFile(OutputFile)
oldfile.Delete
Else
'wscript.echo oldfile & " does not yet exist."
End If
If Silent <= 1 Then
Call CServer
End If
'Bring up inputbox for old server string
Sub CServer
ChangePathFrom = InputBox ("Type the string of text that you wish to"_
& " replace in your shortcuts (LNK Files).","Enter text string to replace",ChangePathFrom)
ChangePathFrom = LCase(ChangePathFrom)
Check4FromSlash = Right(ChangePathFrom,1)
VarLengthCPF = Len(ChangePathFrom)
If Check4FromSlash = "\" Then
VarLengthCPF = VarLengthCPF - 1
ChangePathFrom = Left(ChangePathFrom, VarLengthCPF)
If Silent = 0 Then
wscript.echo "Now Removing trailing '\' from " & ChangePathFrom & "."
End If
End If
If ChangePathFrom = "" Then
wscript.quit
Else
Call NServer
End If
End Sub
'Bring up inputbox for new server string
Sub NServer
'wscript.echo changepathfrom
ChangePathTo = InputBox ("Enter the string of text you would like to " & ""_
& " replace instances of " & Chr(34) & ChangePathFrom & Chr(34) & ""_
& " with.","Enter new text string" & ".",ChangePathTo)
ChangePathTo = LCase(ChangePathTo)
Check4ToSlash = Right(ChangePathTo,1)
VarLengthCPT = Len(ChangePathTo)
If Check4ToSlash = "\" Then
VarLengthCPT = VarLengthCPT - 1
ChangePathTo = Left(ChangePathTo, VarLengthCPT)
If Silent = 0 Then
wscript.echo "Now Removing trailing '\' from " & ChangePathTo & "."
End If
End If
If ChangePathTo = "" Then
Call CServer
Else
Call CFolder
End If
End Sub
'Bring up inputbox for root folder to search (recursive)
Sub CFolder
CheckFolder = InputBox ("Type the root folder path that you wish to"_
& "start your scan from (recursive).","Begin shortcut (lnk) scan"_
& "from:",CheckFolder)
If CheckFolder = "" Then
Call NServer
End If
End Sub
'Start writing the HTM Log file...
Set w = fso.OpenTextFile (OutputFile, ForAppending, True)
w.Writeline ("<html>")
w.Writeline ("<title>Changing Shortcuts in root folder "_
& CheckFolder & "</title>")
w.Writeline ("<table BORDER=0 width=100% cellspacing=0 cellpadding=3>")
w.Writeline ("<tr>")
w.Writeline ("<th bgcolor=#000080 colspan=3 width=100>")
w.Writeline ("<p align=left>")
w.Writeline ("</th>")
w.Writeline ("</tr>")
w.Writeline ("<h0><B><font face=Arial color=#000033 size=2>"_
& "Shortcuts located in: <font color=#CC0000> "_
& CheckFolder & " <font face=Arial color=#000033 size=2>,"_
& " searching recursively at " & CurTime & "</B></font></h0>")
w.WriteLine ("<TR bgcolor=gray colspan=3 width=100>")
w.WriteLine ("<TD><font face=Arial size=1 color=white> Shortcut Path"_
& "</font></TD>")
w.WriteLine ("<TD><font face=Arial size=1 color=white> Target Path"_
& "</font></TD>")
w.WriteLine ("<TD><font face=Arial size=1 color=white> Updated to"_
& "</font></TD>")
w.WriteLine ("</TR>")
If ChangePathFrom = "" Then
wscript.echo "You have not specified a source string to change."
Call Cserver
ElseIf ChangePathTo = "" Then
wscript.echo "You have not specified a new string name to"_
& " replace" & Chr(34) & ChangePathFrom & Chr(34) & " with."
Call Nserver
ElseIf CheckFolder = "" Then
wscript.echo "You must specify a root folder to begin your"_
& " search from."
Call CFolder
End If
'process the shortcuts
ModifyLinks CheckFolder
Sub ModifyLinks (foldername)
dim file 'for stepping through the files collection '
dim folder 'for stepping through the subfolders collection '
dim fullname 'fully qualified link file name '
dim link 'object connected to the link file '
'process all the files in the folder
For each file in fso.GetFolder(foldername).Files
'check only link files
If strcomp(right(file.name,4),".lnk",vbTexctCompare) = 0 then
'Find full path of shortcut
fullname = fso.GetAbsolutePathName(file)
'Find full path of target within shortcut
set link = wso.CreateShortcut(fullname)
targetpath = LCase(link.targetpath)
oldfull = fullname
oldlink = targetpath
newlink = "Not Updated"
'Displays current shortcut that is being checked (good for
' troubleshooting the script).
'If Silent = 0 Then
'MsgBox "Checking shortcut: " & fullname & "." & VBCrlf_
'& "Shortcut target: " & targetpath
'End If
'If the current server (one you want to change) is found in the
' target path, then run the following code
If InStr(1, targetpath, ChangePathFrom) > 0 Then
sChangeTargetTo = ""
sChangePathTo = ""
'Set numerical length of full target path
VarLengthPath = Len(targetpath)
'Set numerical length of ChangePathFrom
VarLengthCPF = Len(ChangePathFrom)
'Find out what's between character 0 and where changepathfrom starts
VarBeginPath = InStr(1, targetpath, ChangePathFrom)
'Subtract 1 from where it begins (all text begins at 1 in a string)
'This is so you will have a '0' value if you type in a root drive or
'UNC to replace - there shouldn't be anything that appears before
''c:\' or '\\server' etc.
VarBeginPath = VarBeginPath - 1
'Parse actual text prior to search string to replace
BeginPath = Null
BeginPath = Left(targetpath, VarBeginPath)
'wscript.echo "VarBeginPath is: " & VarBeginPath & ". " & BeginPath
'Find out how many characters are left after subtracting the beginpath
'and search strings from the whole path
VarEndPath = VarLengthPath - (VarBeginPath + VarLengthCPF)
'Find out what text appears after the search string
EndPath = Right(targetpath, VarEndPath)
'wscript.echo EndPath
workingpath = link.workingdirectory
'Set variable to text before/search string/text after, so you get
'something like: c:\stuffbeforestring\mysearchstring\stuffafterstring
'or c:\temp\docs\mysearchstring\test.doc
sChangePathTo = BeginPath & ChangePathTo & EndPath
'wscript.echo "ChangePathTo is: " & ChangePathTo
'If there is no working directory, then text will show 'not set' during
'script execution
If workingpath = "" Then
workingpath = "not set"
End If
'if you are running in verbose mode, you will be prompted with
'each shortcut and working folder.
If Silent = 0 Then
MyVar = MsgBox ("Path contains " & Chr(34) & ChangePathFrom & "." & Chr(34) & ""_
& " LNK file's full target path is: "_
& targetpath & "." & " Working path is "_
& workingpath & ".",64, fullname)
End If
'Sometimes shortcuts don't have working dirs (not sure why)
'If there is a working dir, then run following code
If workingpath <> "not set" Then
VarBeginPath = InStr(1, workingpath, ChangePathFrom)
If VarBeginPath > 0 Then
VarBeginPath = VarBeginPath - 1
End If
'Parse actual text prior to search string to replace
BeginPath = Null
'wscript.echo "VarBeginPath " & VarBeginPath
BeginPath = Left(workingpath, VarBeginPath)
'wscript.echo "Working beginpath is: " & BeginPath
'Set numerical length of working directory
VarLengthWorking = Len(link.workingdirectory)
VarEndPath = VarLengthWorking - (VarBeginPath + VarLengthCPF)
'wscript.echo "Working path number count is: " & varlengthworking & ""_
'& VBCRLF & "working path end
'wscript.echo "VarEndPath = " & VarEndPath & " = " & VarLengthWorking & ""_
'& " - (" & VarBeginPath & " + " & VarLengthCPF & ")"
'Find out what text appears after the search string
If VarEndPath >= 0 Then
EndPath = Right(workingpath, VarEndPath)
sChangeTargetTo = BeginPath & ChangePathTo & EndPath
'wscript.echo "ChangeTargetTo is: " & sChangeTargetTo
WorkingMSG = "Also change working directory to " & sChangeTargetTo & "?"
End If
'wscript.echo "End of working folder :" & EndPath
Else
link.workingdirectory = ""
WorkingMSG = "No working directory will be set at this time."
End If
'wscript.echo "Path of shortcut is " & targetpath & ""_
'& VBCRLF & ". Working folder is " & workingpath & "."
'Display input box to modify each shortcut as the script finds them
If Silent = 0 Then
ModifyPath = InputBox ("Modifying " & fullname & "." & VBCRLF & ""_
& VBCRLF & "Modify path for " & targetpath & " "_
& "and replace with " & sChangePathTo & "?" & VBCRLF & VBCRLF & ""_
& WorkingMSG,""_
& "Type 'yes' to modify")
ElseIf Silent >= 1 Then
ModifyPath = "yes"
End If
If ModifyPath = "yes" Then
bgcolor = "#99CCFF"
'Set link target path attribute to
link.targetpath = Chr(34) & sChangePathTo & Chr(34)
newlink = link.targetpath
'wscript.echo newlink
If VarLengthWorking <> "" Then
'Set link working dir attribute to
' \\ChangePathToname\workingpath
link.workingdirectory = Chr(34) & sChangeTargetTo & Chr(34)
End If
'Save the shortcut with the new information
link.save
'If answer above is anything but yes, the script will proceed
' to the next shortcut
Else
End if
'Clear link variable
MyPos = 0
MyPosEnd = 0
End if
'write output to logfile
Call WriteEntry
End If
Next
'process all the subfolders in the folder
For each folder in fso.GetFolder(foldername).Subfolders
call ModifyLinks(folder.path)
Next
End Sub
'--------------------------------------------------------------------------
' Function WriteEntry to write change history to logfile in outputfile path
'--------------------------------------------------------------------------
Function WriteEntry
If newlink <> "0" Then
w.WriteLine ("<TR bgcolor=" & Chr(34) & bgcolor & Chr(34) & ">")
w.WriteLine ("<TD><font face=Arial color=#000033 size=1>" & ""_
& oldfull & "</font></TD>")
w.WriteLine ("<TD><font face=Arial color=#000033 size=1>" & ""_
& oldlink & "</font></TD>")
w.WriteLine ("<TD><font face=Arial color=#000033 size=1>" & ""_
& newlink & "</font></TD>")
w.WriteLine ("</TR>")
oldfull = "0"
newlink = "0"
oldlink = "0"
bgcolor = "white"
End If
End Function
'----------------------------------------------------------------------------
'Function to see if outputfile already exists
'----------------------------------------------------------------------------
Function CheckFileExists(sFileName)
Dim FileSystemObject
Set FileSystemObject = CreateObject("Scripting.FileSystemObject")
If (FileSystemObject.FileExists(sFileName)) Then
CheckFileExists = True
Else
CheckFileExists = False
End If
Set FileSystemObject = Nothing
End Function
w.Writeline ("</html>")
'if silent = 2, then it will not open the log file
If Silent <= 1 Then
'set command variable with path in quotes (for long filenames)
Command = Chr(34) & OutputFile & Chr(34)
'run htm file in your default browser
wso.Run Command
End If
'~~[/script]~~