Any Scripting Experts in the house?
Hello everybody, I'm a helpdesk tech looking to expand his horizons and I've run into an issue that I'm having lots of trouble with.
I'm trying to modify a vb script that i found that will allow us to use microsoft's user state migration tool 4.0 along with psexec to automatically migrate a users profile from a windows xp machine to windows 7
This is the snippet of code that I
\\ttc01\userdata\usmt\PSTools\PsExec.exe \\pc-cgbmxb1 -s \\ttc01\userdata\usmt\x86\scanstate.exe c:\Temp\Migdata\lmesa\pc-cgbmxb1 /v:13 /i:\\ttc01\userdata\usmt\x86\Migapp.xml /i:\\ttc01\userdata\usmt\x86\MigDocs.xml /i:\\ttc01\userdata\usmt\x86\miguser.xml /progress:c:\Temp\MigData\lmesa\ScanStateProg.log /l:c:\Temp\MigData\lmesa\ScanState.log /ui:Nash\lmesa /c /vsc
This is the full line of code that is supposed to be exected on the target machine but I seem to be having an issue with just the first line:
\\ttc01\userdata\usmt\PSTools\PsExec.exe \\pc-cgbmxb1 -s \\ttc01\userdata\usmt\x86\scanstate.exe
basically psexec is not able to get to scanstate.exe and i believe this is because command prompts/dos will not see the scanstate.exe because it is using unc path
i know theres a way around this but I can't seem to find out
usmt.vbs
Comments
Ian,
You are correct, it's because psexec.exe can't see the UNC path. It's called the "double-hop" problem. The only way around it is to send the credentials along with the command. Psexec has the -u and -p parameters (user and password). Alternatively, you can use PDQ Deploy and the "other credentials" option to deploy the script file and this would take care of it.
There is one more thing to be aware of. The length of the command. CMD has limits. See http://support.microsoft.com/kb/830473
One other thing I came around is that psexec has some issues running Windows 7. (that was when I discovered PDQ Deploy)
My suggestion is that you should create a simple exe package, deploy it and run locally. As I mentioned here before i do it all the time using winrar's self extracting feature. (can run virtually anything after extraction)
I agree with both Adam and Selfman. One point to add, however... if you do use any of the PSTools and you are using any version released since Microsoft purchased them (Microsoft purchased all the SysInternals tools several years ago) you will want to add the
argument to the command line. This isn't a problem if any tool you are using has been executed on the target machine and the EULA has been accepted. Since this is rare I suggest just passing this switch.
im getting this error when i attempt to run the script and also it does not write any data on the target machine
okay you guys i know exactly what the problem is but do not know how to script around it.
\\ttc01\userdata\usmt\PSTools\PsExec.exe \\pc-cgbmxb1 -s \\ttc01\userdata\usmt\x86\scanstate.exe c:\Temp\Migdata\lmesa\pc-cgbmxb1 /v:13 /i:\\ttc01\userdata\usmt\x86\Migapp.xml /i:\\ttc01\userdata\usmt\x86\MigDocs.xml /i:\\ttc01\userdata\usmt\x86\miguser.xml /progress:c:\Temp\MigData\lmesa\ScanStateProg.log /l:c:\Temp\MigData\lmesa\ScanState.log /ui:Nash\lmesa /c /vsc
this is the full line of code that I'm trying to execute
this is thepart thats broken
\\ttc01\userdata\usmt\PSTools\PsExec.exe \\pc-cgbmxb1 -s \\ttc01\userdata\usmt\x86\scanstate.exe
i tried to execute the rest of it without using psexec from the target machine and it executed beautifully with no problems.
This is what i executed from the target machine and it seemed to work just fine
\\ttc01\userdata\usmt\x86\scanstate.exe c:\Temp\Migdata\lmesa\pc-cgbmxb1 /v:13 /i:\\ttc01\userdata\usmt\x86\Migapp.xml /i:\\ttc01\userdata\usmt\x86\MigDocs.xml /i:\\ttc01\userdata\usmt\x86\miguser.xml /progress:c:\Temp\MigData\lmesa\ScanStateProg.log /l:c:\Temp\MigData\lmesa\ScanState.log /ui:Nash\lmesa /c /vsc
can anyone think of an alternate way to call on psexec to run this command? or an even different way then that?
It's probably a permissions issue. When psexec runs without a user name and password (or with the -s switch) it runs on the target computer as "Local System" which doesn't have any rights to network resources. You should be able to run this tio test:
You should get an "Access is denied" error. You have a couple of options.
There may be some other solutions, but that's all I can think of off the top of my head.
I am not sure if it's been mentioned, but you need to use a accout which is a member of the network service group.
Thanks for the thoughts I don't think it is permissions issue but I'm going to try and add the user account and password for psexec to use to see if that helps
I was thinking maybe it would be better doing it with net use command and mapping a drive instead of using unc path would that be better maybe?
It would make it easier to read and cut down on the length of the command line, but mapped drives would have the same permissions issues as UNC.
which permissions would need to be added to ensure that this script won't have any permissions issues? would I add permissions on the network share or add permissions into the script?
You can go either way. Either put in a user name and password into the script for psexec or grant rights to the file share to all of your computer accounts in AD.
But, it would probably save you hassle in the long run if you just copied all of the files to the computers first before running the command, that way there's no need for the command to hit the network and run into permission problems.
Thats true i'm going to make a directory in the temp folder for the scan state files c:\temp\scanstate
K i''ll keep you posted
As I stated multiple times, why not to use a selfextracting archive? In my case it saved a lot of trouble.
Lolz sorry selfman I've just never known have to use winrar's selfextracting archive wouldn't know where to start
hint:
- select files you want to deploy
- right mouse click - add to archive
- in followin winrar window check Create sfx archive
- in TAB Advanced click sfx options
- TAB general - enter script name you want to run "run after extraction"
- TAB modes - select unpack in temporary folder, Silent mode - hide all
- TAB update - select extract and replace files and overwrite all files
- confirm OK, OK and voila a basic self extracting archive is created
Hope this helps
Oh and one more thing - if this is comlicated for you ;-) you can still use the iExpress tool.
Start > Run > iexpress<enter> an follow the wizard.
(some blah blah with screenshots are here http://babek.info/libertybasicfiles/lbnews/nl134/iexpress.htm )
Awesome let me give this a try
I was able to get this script working by taking out psexec. I also modified it a bit to save the file to one of our network shares. Thanks for all those that helped me through this one. REM ***************************************************************************REM *** Program: USMT_New_Computer.vbs
REM *** Author: Guy Pletcher
REM *** Created: 21 February 2010
REM *** Edited: 16 December 2011
REM ***
REM *** Description: This script will execute the USMT, migrating data from
REM *** the old machine to the store folder on ttc01. the target PC must be on
REM *** the mcskc domain. You will be prompted to enter the old
REM *** computer name, ttc01, and the username that you would like to backup.
REM *** This is the only interaction required. A status window
REM *** will appear giving the status of each state of the
REM *** migration. Error checking has been included in the
REM *** coding and returns an error if one if generated. The USMT
REM *** has been customized for the command prompt window to be
REM *** minimized so that it can be restored if need be for
REM *** troubleshooting/status purposes.
REM ***
REM *** The global variable, USMTLocation , contains the network
REM *** location of where the USMT 4.0 is located, specifically
REM *** this VBScript. Both USMT 4.0 x86 and x64 must be located
REM *** at % USMTLocation%\x86 and % USMTLocation%\x64, as this
REM *** script is set to automatically determine the architecture
REM *** of the old machine and runs the appropriate USMT version.
REM *** In our example it is \\ttc01\userdata\usmt\
REM *** %USMTLocation%\
REM *** This is to run the scanstate, and robocopy
REM *** locally on the machines so that bandwidth and speed are
REM *** not compromised.
REM *** 1) Create HTML Display Status Window
REM *** 2) Enter Source PC, Destination PC, and Username
REM *** 3) Delete Old USMT folders and Create New USMT Folders
REM *** 4) Determine if the system is x86 or x64
REM *** 5) Perform USMT Migration on Old Machine
REM *** 6) Exit Script if USMT Migration Failed
REM *** 7) Copy Migrated USMT data to New Machine
REM *** 8) Cleanup Global Variables
REM ***
REM ***************************************************************************
Option Explicit
REM Define Global Constants
CONST USMTLocation = "\\ttc01\userdata\usmt\"
REM Define Global Objects
DIM objIE : Set objIE = CreateObject("InternetExplorer.Application")
REM Define Global Variables
DIM OldComputer : Set OldComputer = Nothing
DIM NewComputer : Set NewComputer = Nothing
DIM ReturnCode : Set ReturnCode = Nothing
DIM UserName : Set UserName = Nothing
DIM USMTSourceCMD : USMTSourceCMD = "0"
DIM USMTDestCMD : USMTDestCMD = "0"
REM Create HTML Display Status Window
CreateDisplayWindow()
REM Enter Source PC, Destination PC, and Username
GetComputerInfo()
REM Delete Old USMT folders and Create New USMT Folders
CreateUSMTFolders()
REM Determine if the system is x86 or x64
DetermineArchitecture()
REM Perform USMT Migration on Old Machine
USMTMigrate()
REM Exit Script if USMT Migration Failed
VerifyScanState()
REM Copy Migrated USMT data to New Machine
CopyUSMTData()
REM Load Migrated USMT data on New Machine
REM Cleanup Global Variables
GlobalVariableCleanUp()
'******************************************************************************
'******************************************************************************
Sub CreateDisplayWindow()
REM Define Local Constants
CONST strComputer = "."
REM Define Local Objects
DIM objWMIService : Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
DIM colItems : Set colItems = objWMIService.ExecQuery ("Select PelsWidth,PelsHeight From Win32_DisplayConfiguration")
DIM objItem : Set objItem = Nothing
REM Define Local Variables
DIM intWidth : intWidth = 320
DIM intHeight : intHeight = 240
DIM intScreenWidth : Set intScreenWidth = Nothing
DIM intScreenHeight : Set intScreenHeight = Nothing
For Each objItem in colItems
intScreenWidth = objItem.PelsWidth
intScreenHeight = objItem.PelsHeight
Next
objIE.Navigate "about:blank"
objIE.Toolbar = 0
objIE.StatusBar = 0
objIE.AddressBar = 0
objIE.MenuBar = 0
objIE.Resizable = 0
While objIE.ReadyState <> 4
WScript.Sleep 100
Wend
objIE.Left = (intScreenWidth / 2) - (intWidth / 2)
objIE.Top = (intScreenHeight / 2) - (intHeight / 2)
objIE.Visible = True
REM Cleanup Local Variables
Set colItems = Nothing
Set intScreenWidth = Nothing
Set intScreenHeight = Nothing
Set intWidth = Nothing
Set intHeight = Nothing
Set objItem = Nothing
Set objWMIService = Nothing
End Sub
'******************************************************************************
Sub GetComputerInfo()
OldComputer = InputBox( "Enter the old computer name:" )
NewComputer = InputBox( "Enter ttc01 here:" )
UserName = InputBox( "Enter the username:" )
objIE.Document.WriteLn "<FONT SIZE=8>USMT migration of " & UserName & " from " & OldComputer & " to " & NewComputer & "</FONT><BR><BR><BR>"
End Sub
'******************************************************************************
Sub CreateUSMTFolders()
On Error Resume Next
REM Define Local Objects
DIM FSO : SET FSO = CreateObject("Scripting.FileSystemObject")
REM Define Local Variables
DIM comp : Set comp = Nothing
DIM DeleteFolder : Set DeleteFolder = Nothing
DIM TMP : TMP = "\\" & OldComputer & "\c$\Temp"
DIM MigData : MigData = TMP & "\MigData"
DIM USMTPath : USMTPath = MigData & "\" & UserName & "\" & OldComputer
objIE.Document.WriteLn "Creating USMT Folders....."
REM Delete old USMTPATH, if exists
If FSO.FolderExists(USMTPath) then
Set DeleteFolder = FSO.GetFolder(USMTPath)
DeleteFolder.Delete
End If
If FSO.FolderExists(MigData & "\" & UserName) then
Set DeleteFolder = FSO.GetFolder(MigData & "\" & UserName )
DeleteFolder.Delete
End If
If FSO.FolderExists(MigData) then
Set DeleteFolder = FSO.GetFolder(MigData)
DeleteFolder.Delete
End If
REM Create USMTPATH
If NOT FSO.FolderExists(TMP) then
FSO.CreateFolder(TMP)
End If
FSO.CreateFolder(MigData)
FSO.CreateFolder(MigData & "\" & UserName)
FSO.CreateFolder(MigData & "\" & UserName & "\" & OldComputer)
If FSO.FolderExists(USMTPath) then
objIE.Document.WriteLn "Success" & "<BR><BR>"
else
objIE.Document.WriteLn "Failure" & "<BR><BR>"
End If
REM Cleanup Local Variables
Set FSO = Nothing
Set comp = Nothing
Set TMP = Nothing
Set TMP = Nothing
Set MigData = Nothing
Set USMTPath = Nothing
Set DeleteFolder = Nothing
End Sub
'******************************************************************************
Sub DetermineArchitecture()
REM Define Local Objects
DIM FSO : SET FSO = CreateObject("Scripting.FileSystemObject")
DIM objWMIService : Set objWMIService = Nothing
DIM objWMIServiceSet : Set objWMIServiceSet = Nothing
DIM colOperatingSystems : Set colOperatingSystems = Nothing
DIM objOperatingSystem : Set objOperatingSystem = Nothing
REM Define Local Variables
DIM x86RUNPATH : x86RUNPATH = USMTLocation & "x86"
DIM x64RUNPATH : x64RUNPATH = USMTLocation & "x64"
DIM OSSourceType : OSSourceType = "\\" & OldComputer & "\c$\Program Files (x86)"
DIM OSDestType : OSDestType = "\\" & NewComputer & "\c$\Program Files (x86)"
DIM msgSource : Set msgSource = Nothing
DIM msgDest : Set msgDest = Nothing
Set objWMIService = GetObject("winmgmts:\\" & OldComputer & "\root\cimv2")
Set colOperatingSystems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem")
For Each objOperatingSystem in colOperatingSystems
msgSource = objOperatingSystem.Caption
Next
objIE.Document.WriteLn "Determining Source Architecture....."
If FSO.FolderExists(OSSourceType) Then
USMTSourceCMD = x64RUNPATH
else
USMTSourceCMD = x86RUNPATH
End IF
If NOT USMTSourceCMD = "0" then
objIE.Document.WriteLn "Success" & "<BR>"
else
objIE.Document.WriteLn "Failure(" & ReturnCode & ")" & "<BR>"
End If
objIE.Document.WriteLn "Determining Destination Architecture....."
Set objWMIService = GetObject("winmgmts:\\" & NewComputer & "\root\cimv2")
Set colOperatingSystems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem")
For Each objOperatingSystem in colOperatingSystems
msgDest = objOperatingSystem.Caption
Next
If FSO.FolderExists(OSDestType) Then
USMTDestCMD = x64RUNPATH
else
USMTDestCMD = x86RUNPATH
End IF
If NOT USMTDestCMD = "0" then
objIE.Document.WriteLn "Success" & "<BR>"
else
objIE.Document.WriteLn "Failure(" & ReturnCode & ")" & "<BR>"
End If
objIE.Document.WriteLn " Source: " & msgSource &_
Chr(32) & Right(USMTSourceCMD,3) & "<BR>"
objIE.Document.WriteLn " Destination: " & msgDest & Chr(32) & Right(USMTDestCMD,3) & "<BR><BR>"
REM Cleanup Variables
Set colOperatingSystems = Nothing
Set FSO = Nothing
Set msgDest = Nothing
Set msgSource = Nothing
Set x86RUNPATH = Nothing
Set x64RUNPATH = Nothing
Set objWMIService = Nothing
Set objWMIServiceSet = Nothing
Set OSSourceType = Nothing
Set OSDestType = Nothing
Set objOperatingSystem = Nothing
End Sub
'******************************************************************************
Sub USMTMigrate()
REM Define Local Objects
DIM oShell : SET oShell = CreateObject("Wscript.Shell")
REM Define Local Variables
DIM Debug : Debug = "13"
DIM TMP : TMP = "c:\Temp"
DIM MigData : MigData = TMP & "\MigData"
DIM LOGPATH : LOGPATH = MigData & "\" & UserName
DIM StorePATH : StorePATH = MigData & "\" & UserName & "\" & OldComputer
DIM USMT : USMT = USMTSourceCMD & "\scanstate.exe " & StorePATH & " /v:" & Debug & " /i:" & USMTSourceCMD &_
"\Migapp.xml /i:" & USMTSourceCMD & "\MigDocs.xml /i:" & USMTSourceCMD & "\miguser.xml /progress:" & LOGPATH &_
"\ScanStateProg.log /l:" & LOGPATH & "\ScanState.log /ui:mcskc\" & UserName & " /c /vsc"
objIE.Document.WriteLn "Executing Scanstate on " & OldComputer & "....."
ReturnCode = oShell.Run(USMT, 7, True)
If ReturnCode = "0" then
objIE.Document.WriteLn "Success" & "<BR><BR>"
else
objIE.Document.WriteLn "Failure(" & ReturnCode & ")" & "<BR><BR>"
End If
REM Cleanup Variables
Set Debug = Nothing
SET oShell = Nothing
SET TMP = Nothing
SET MigData = Nothing
SET LOGPATH = Nothing
SET StorePATH = Nothing
Set USMT = Nothing
End Sub
'******************************************************************************
Sub VerifyScanState()
If NOT ReturnCode = "0" then
MsgBox("The data migration on " & OldComputer & " failed due to error" & ReturnCode &_
". Please check the log file located at & \\" & OldComputer & "\c$\Temp\MigData\ScanLog.log.")
GlobalVariableCleanUp()
WScript.Quit
Else
Set ReturnCode = Nothing
End If
End Sub
'******************************************************************************
Sub CopyUSMTData()
REM Define Local Objects
DIM FSO : SET FSO = CreateObject("Scripting.FileSystemObject")
DIM oShell : SET oShell = CreateObject("Wscript.Shell")
REM Define Local Variables
DIM SourceUSMTPath : SourceUSMTPath = "\\" & OldComputer & "\c$\Temp\MigData"
DIM DestUSMTPath : DestUSMTPath = "\\" & NewComputer & "\userdata\usmt\Store"
DIM Parameters : Parameters = "/e /eta /mir"
DIM RoboCopyCMD : RoboCopyCMD = "RoboCopy.exe" & Chr(32) & SourceUSMTPath & Chr(32) & DestUSMTPath &_
Chr(32) & Parameters
objIE.Document.WriteLn "Copying USMT folder from " & OldComputer & " to " & NewComputer & "....."
oShell.Run RoboCopyCMD, 7, True
If FSO.FolderExists(DestUSMTPath) then
objIE.Document.WriteLn "Success" & "<BR><BR>"
else
objIE.Document.WriteLn "Failure" & "<BR><BR>"
End If
REM Cleanup Variables
Set FSO = Nothing
Set oShell = Nothing
SET SourceUSMTPath = Nothing
SET DestUSMTPath = Nothing
Set Parameters = Nothing
Set RoboCopyCMD = Nothing
End Sub
'******************************************************************************
'Sub LoadUSMTData()
'
' REM Define Local Objects
' DIM oShell : SET oShell = CreateObject("Wscript.Shell")
'
' REM Define Local Variables
' DIM Debug : Debug = "13"
' DIM TMP : TMP = "c:\Temp"
' DIM MigData : MigData = TMP & "\MigData"
' DIM LOGPATH : LOGPATH = MigData & "\" & UserName
' DIM StorePATH : StorePATH = MigData & "\" & UserName & "\" & OldComputer
' DIM USMT : USMT = USMTDestCMD & "\loadstate.exe " & StorePATH & " /v:" & Debug & " /i:" & USMTDestCMD &_
' "\Migapp.xml /i:" & USMTDestCMD & "\MigDocs.xml /i:" & USMTDestCMD & "\miguser.xml /progress:" &_
' LOGPATH & "\LoadStateProg.log /l:" & LOGPATH & "\LoadState.log /ui:mcskc\" & UserName & " /c"
'
'
' objIE.Document.WriteLn "Executing Loadstate on " & NewComputer & "....."
' ReturnCode = oShell.Run(USMT, 7, True)
' If ReturnCode = "0" then
' objIE.Document.WriteLn "Success" & "<BR><BR>"
' else
' objIE.Document.WriteLn "Failure(" & ReturnCode & ")" & "<BR><BR>"
' End If
'
' REM Cleanup Variables
' Set Debug = Nothing
' SET oShell = Nothing
' SET TMP = Nothing
' SET MigData = Nothing
' SET LOGPATH = Nothing
'
'End Sub
'******************************************************************************
'Sub VerifyLoadState()
'
' If NOT ReturnCode = "0" then
' MsgBox("The data migration on " & NewComputer & " failed due to error " & ReturnCode & ". Please check the log file located at & \\" &_
' NewComputer & "\c$\Temp\MigData\LoadState.log.")
' GlobalVariableCleanUp()
' objIE.Quit
' WScript.Quit
' Else
' MsgBox("The data successfully migrated from " & OldComputer & " to " & NewComputer & ".")
' End If
'
'End Sub
'******************************************************************************
Sub GlobalVariableCleanUp()
objIE.Quit
Set OldComputer = Nothing
Set objIE = Nothing
Set NewComputer = Nothing
Set ReturnCode = Nothing
Set UserName = Nothing
Set USMTSourceCMD = Nothing
Set USMTDestCMD = Nothing
End Sub