Any Scripting Experts in the house?

Comments

19 comments

  • Adam Ruth

    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.

    0
    Comment actions Permalink
  • 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)

    0
    Comment actions Permalink
  • Shane Corellian

    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.

    0
    Comment actions Permalink
  • 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

    0
    Comment actions Permalink
  • 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?

    0
    Comment actions Permalink
  • Adam Ruth

    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.

    0
    Comment actions Permalink
  • 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.

    0
    Comment actions Permalink
  • 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

    0
    Comment actions Permalink
  • 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?

    0
    Comment actions Permalink
  • Adam Ruth

    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.

    0
    Comment actions Permalink
  • 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?

    0
    Comment actions Permalink
  • Adam Ruth

    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.

    0
    Comment actions Permalink
  • 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 

    0
    Comment actions Permalink
  • SelfMan

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

    0
    Comment actions Permalink
  • Ian Fitzpatrick

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

    0
    Comment actions Permalink
  • 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

    0
    Comment actions Permalink
  • 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 )

    0
    Comment actions Permalink
  • Ian Fitzpatrick

    Awesome let me give this a try

    0
    Comment actions Permalink
  • 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
     

    0
    Comment actions Permalink

Please sign in to leave a comment.