Discussion Forums/PDQ Deploy/Deploy - Questions

Answered

Any Scripting Experts in the house?

Ian Fitzpatrick
asked this on December 02, 2011 15:24

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

 

 

Comments

User photo
Adam Ruth
Admin Arsenal

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.

December 04, 2011 13:09
User photo
SelfMan

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)

December 04, 2011 13:52
User photo
Shane Corellian
Admin Arsenal

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

 /accepteula 

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.

December 05, 2011 17:02
User photo
Ian Fitzpatrick

im getting this error when i attempt to run the script and also it does not write any data on the target machine

December 09, 2011 12:26
User photo
Ian Fitzpatrick

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?

December 09, 2011 12:43
User photo
Adam Ruth
Admin Arsenal

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:

\\ttc01\userdata\usmt\PSTools\PsExec.exe \\pc-cgbmxb1 -s cmd /c dir \\ttc01\userdata\usmt\x86\scanstate.exe 

You should get an "Access is denied" error. You have a couple of options. 

  1. Run the command with a user name and password that has rights to read file share.
  2. Grant read access to the file share to all of the computer accounts (requires that they all be Active Directory).
  3. Copy the scanstate.exe program to all computers before running psexec and run it locally.

There may be some other solutions, but that's all I can think of off the top of my head.

December 09, 2011 13:28
User photo
SelfMan

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.

December 09, 2011 13:51
User photo
Ian Fitzpatrick

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

December 09, 2011 14:12
User photo
Ian Fitzpatrick

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?

December 09, 2011 15:58
User photo
Adam Ruth
Admin Arsenal

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.

December 09, 2011 16:47
User photo
Ian Fitzpatrick

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?

December 09, 2011 17:13
User photo
Adam Ruth
Admin Arsenal

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.

December 09, 2011 17:16
User photo
Ian Fitzpatrick

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 

December 09, 2011 17:20
User photo
SelfMan

As I stated multiple times, why not to use a selfextracting archive? In my case it saved a lot of trouble.

December 09, 2011 17:21
User photo
Ian Fitzpatrick

Lolz sorry selfman I've just never known have to use winrar's selfextracting archive wouldn't know where to start

December 09, 2011 17:23
User photo
SelfMan

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

December 09, 2011 17:32
User photo
SelfMan

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 )

December 09, 2011 17:40
User photo
Ian Fitzpatrick

Awesome let me give this a try

December 09, 2011 17:47
User photo
Ian Fitzpatrick

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 "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Source:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; " & msgSource &_ 
Chr(32) & Right(USMTSourceCMD,3) & "<BR>" 
objIE.Document.WriteLn "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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
 

December 19, 2011 13:15