copy file to every users profile?

Started by bilbo6209, July 18, 2014, 11:21:25 AM

Previous topic - Next topic

bilbo6209

Hello all,

I am trying to figure out how to copy a config file to every Windows users profile \appdata\local\program name\folder.

I have a VBScript that works great,but when I attempted to call it through my winbatch script using the runwait command it doesnt appear to run with Admin(or system) rights as the Winbatch is launched... So I am looking for help either to get Winbatch to run the VBScript with inherited rights, or possibly help getting the same functionality that is in the VBScript incorporated into my Winbatch script.

My VBScript cycles through the registry looking for each user profile name, then looks for the required folder, if it isn't there it is supposed to create it, then copies the required file from the home directory to the desired location and then steps onto the next users profile. 

td

You can easily translate almost all VBS scripts to WinBatch. It usually involves little more than removing any 'Set' key words, the space between 'for' and 'each' in any for each loops and line continuation operators by placing the continued lines on one line.

Alternatively, you can recode your VBS script to use native WinBatch functions.

If you chose to run your VBS script from WinBatch, by default the WinBatch 'Run' functions, with the exception of 'RunWithLogon', pass their access token to the process being started.  This means that if the WinBatch script is running as an elevated Admin, the VBS script will run as an elevated Admin.  It also means that if WinBatch is running as restricted Admin or Standard user, the VBS script will run as a restricted Admin or Standard user. If you are using a compiled script, you can change the manifest settings of the script to 'requirerAdministrator' to force the script to run as an admin, assuming UAC is enabled on the system.  If UAC is not enabled and you are running the script from a standard user account on Windows 7, you would need use 'RunWithLogon' to run the script as an administrator.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

etippelt

Have you considered active setup?  Just put the file in a common area, and let active setup run the copy for you whenever a new user logs in. Works with both local and roaming profiles. The details can be found here:
www.etlengineering.com/installer/activesetup.txt
Using Winbatch since 1995. Excellent tool, awesome support always.

td

Or you could use a login script or use the Task Scheduler, if your goal is to perform the task on a per user basis.

Here is a MSDN blog post describing one use of Active Setup:

http://blogs.msdn.com/b/aruns_blog/archive/2011/06/20/active-setup-registry-key-what-it-is-and-how-to-create-in-the-package-using-admin-studio-install-shield.aspx
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

bilbo6209

Where I am contracted currently they do not want anything to run on user logon, I specificly asked about Active Setup when I started here and they specificly say NO... so Active setup and users logon scripts are out... hmmm as to the "pass their access token to the process being started" I am running Winbatch as the system account using PSExec (so the install mimics the install behavior of our software distribution system as closly as possible) with your comment stating it should be passing the access token, that would imply that the VB I am calling with the runshell command should be running as the system acct, but it doesnt appear that it is.

If Winbatch can typically handle VBScript code, then this code should work?

Option Explicit
Dim objWshShell, objFSO, strScriptFileDirectory
Dim strAllUsersDesktopPath, strUserProfilesMainFolder
Dim objFolder, objFolderItem, strAppDataFolder

Set objWshShell = WScript.CreateObject("WScript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
strScriptFileDirectory = objFSO.GetParentFolderName(wscript.ScriptFullName)

strAllUsersDesktopPath = objWshShell.RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\Common Desktop")
' Attempts to configure Windows 2000/XP paths.
strUserProfilesMainFolder = Mid(strAllUsersDesktopPath,1,InStr(strAllUsersDesktopPath, "\All Users"))
If strUserProfilesMainFolder = "" Then
   ' Windows 2000/XP paths are not valid, so attempting to configure Windows Vista/7 paths.
   strUserProfilesMainFolder = Mid(strAllUsersDesktopPath,1,InStr(strAllUsersDesktopPath, "\Public"))
End If

Set objFolder = objFSO.GetFolder(strUserProfilesMainFolder).Subfolders
ForEach objFolderItem in objFolder
   If objFolderItem = (strUserProfilesMainFolder & "LocalService") Then
      'This one is not a valid user folder, so we ignore it.
   Else
      If objFolderItem = (strUserProfilesMainFolder & "NetworkService") Then
         'This one is not a valid user folder, so we ignore it.
      Else
         If objFolderItem = (strUserProfilesMainFolder & "Public") Then
            'This one is not a valid user folder, so we ignore it.
         Else
            'The following example may not be valid for all directories in the user profile folder - it's here to help illustrate how to determine between an XP and a 7 directory structure in a key location.
            If objFSO.FolderExists (objFolderItem & "\Application Data") Then
               strAppDataFolder = objFolderItem & "\Application Data"
            Else
               strAppDataFolder = objFolderItem & "\AppData\Local"
            End If
            If Not objFSO.FolderExists (strAppDataFolder & "\3M") Then
               objFSO.CreateFolder (strAppDataFolder & "\3M")
            End If
            If Not objFSO.FolderExists (strAppDataFolder & "\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3") Then
               objFSO.CreateFolder (strAppDataFolder & "\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3")
            End If
            If Not objFSO.FolderExists (strAppDataFolder & "\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3\2.6.141.0") Then
               objFSO.CreateFolder (strAppDataFolder & "\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3\2.6.141.0")
            End If
            If objFSO.FileExists (strScriptFileDirectory & "\user.config") Then
               objFSO.CopyFile (strScriptFileDirectory & "\user.config"), (strAppDataFolder & "\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3\2.6.141.0\user.config"), True
            End If
         End If
      End If
   End If
Next

Wscript.Quit

Bill

td

Quote from: bilbo6209 on July 21, 2014, 12:34:43 PM
Where I am contracted currently they do not want anything to run on user logon, I specificly asked about Active Setup when I started here and they specificly say NO... so Active setup and users logon scripts are out... hmmm as to the "pass their access token to the process being started" I am running Winbatch as the system account using PSExec (so the install mimics the install behavior of our software distribution system as closly as possible) with your comment stating it should be passing the access token, that would imply that the VB I am calling with the runshell command should be running as the system acct, but it doesnt appear that it is.

The only time RunShell should start a process with an access token other than the current WinBatch process access token is when it is preceded by a call to  wntRunAsUser.  It is simply the way the underlying Win32 API works. So either the script is not running with the credentials you think for some reason or the problem has been miss diagnosed.   

Quote
If Winbatch can typically handle VBScript code, then this code should work?

In a word, no.   Probably should have but I hadn't anticipated that you would take my comment as an all inclusive list rather than a list of the most common conversion changes.  You do have to use WinBatch syntax. So you would need to remove the 'dim' statements, use the colon character instead of the ampersand character for string concatenation, and WinBatch doesn't have a 'Mid' and 'Instr' functions but it does have the StrSub ans StrIndex functions are similar.   You also need to use the WinBatch comment character for comments and make sure your method call parameters are surrounded by parenthesis.   For those familiar with WinBatch syntax it is usually trivial with the exception that some VBS scripts use default methods which need to be explicitly called in WinBatch script.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

td

Here is a completely untested and therefore guaranteed to be buggy conversion but at least it is a start:
Code (winbatch) Select
objWshShell = CreateObject("WScript.Shell")
objFSO = CreateObject("Scripting.FileSystemObject")
strScriptFileDirectory = DirScript()

strAllUsersDesktopPath = objWshShell.RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\Common Desktop")
; Attempts to configure Windows 2000/XP paths.
strUserProfilesMainFolder = StrSub(strAllUsersDesktopPath,1,StrIndex(strAllUsersDesktopPath, "\All Users", 1, @Fwdscan))
If strUserProfilesMainFolder == "" Then
   ; Windows 2000/XP paths are not valid, so attempting to configure Windows Vista/7 paths.
   strUserProfilesMainFolder = StrSub(strAllUsersDesktopPath,1,StrIndex(strAllUsersDesktopPath, "\Public", 1, @Fwdscan))
End If

objFolder = objFSO.GetFolder(strUserProfilesMainFolder).Subfolders
ForEach objFolderItem in objFolder
strPath = objFolderItem.Path
   If strPath  == (strUserProfilesMainFolder : "LocalService") Then
      ;This one is not a valid user folder, so we ignore it.
   Else
      If strPath  == (strUserProfilesMainFolder : "NetworkService") Then
         ;This one is not a valid user folder, so we ignore it.
      Else
         If strPath  == (strUserProfilesMainFolder : "Public") Then
            ;This one is not a valid user folder, so we ignore it.
         Else
            ;The following example may not be valid for all directories in the user profile folder - it's here to help illustrate how to determine between an XP and a 7 directory structure in a key location.
            If objFSO.FolderExists(:strPath  : "\Application Data") Then
               strAppDataFolder = strPath  : "\Application Data"
            Else
               strAppDataFolder = strPath  : "\AppData\Local"
            EndIf
            If !objFSO.FolderExists(:strAppDataFolder : "\3M") Then
               objFSO.CreateFolder(:strAppDataFolder : "\3M")
            EndIf
            If !objFSO.FolderExists(:strAppDataFolder : "\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3") Then
               objFSO.CreateFolder( :strAppDataFolder : "\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3")
            EndIf
            If !objFSO.FolderExists(:strAppDataFolder : "\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3\2.6.141.0") Then
               objFSO.CreateFolder(:strAppDataFolder : "\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3\2.6.141.0")
            EndIf
            If objFSO.FileExists(:strScriptFileDirectory : "\user.config") Then
               objFSO.CopyFile(:strScriptFileDirectory : "\user.config", strAppDataFolder : "\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3\2.6.141.0\user.config", @True)
            EndIf
         EndIf
      EndIf
   EndIf
Next

exit


"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

td

For what it is worth, there is an example of a default method call in your script.  The lines containing 'objFolderItem &' are actually calling the default method 'Path' on the object 'objFolderItem'.

In WinBatch this is handled by making an explicit call as represented by the following line
Code (winbatch) Select
strPath = objFolderItem.Path
and then using the 'strPath'  variable instead of the implicit calls to the method 'Path' as done by the VB script.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

etippelt

I suppose copying the file in a login script or via group policy is also not permitted?
Using Winbatch since 1995. Excellent tool, awesome support always.

bilbo6209

TD thank you for all your info and help!!
We are using HP Radia to deploy software, all installs run as SYSTEM. Users are locked down and the install runs, writes to the registry etc with no issues so I know that the Winbatch script is running with elivated rights. It is just when the runshell calls the vbs that I receive an Access denied. I know the VB that I supplied is kind of messy, is there a better way to do this? specifily I need to copy a file to every users \appdata\local\3m\{blah}\{blah} folder (including the default user so the file is there when a new profile is created). 


etippelt, no where I am at they do not allow the packagers to add things to logon scripts, active setup, or GPO  :( I have used Active setup at a differnet client and it worked great! This client is VERY concerned about boot and logon times so nothing can slow those down at all!

Bill

td

Quote from: bilbo6209 on July 22, 2014, 08:52:35 AM
TD thank you for all your info and help!!
We are using HP Radia to deploy software, all installs run as SYSTEM. Users are locked down and the install runs, writes to the registry etc with no issues so I know that the Winbatch script is running with elivated rights. It is just when the runshell calls the vbs that I receive an Access denied.

How are you receiving the 'Access denied' error? Is it a WinBatch error or a VBS error?  How exactly are you calling the VBS script with RunShell?  Are you using a compiled WinBatch script? Again RunShell can only pass its access token to the child process.
Quote

I know the VB that I supplied is kind of messy, is there a better way to do this? specifily I need to copy a file to every users \appdata\local\3m\{blah}\{blah} folder (including the default user so the file is there when a new profile is created). 

Check out the WinBatch native registry functions alone with the FileCopy function.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

etippelt

Is this config file part of an MSI install?  It would be trivial to include this in a way that allows self healing to install the file when the user activates any advertised entry point (assuming the MSI has advertised entry points).
Using Winbatch since 1995. Excellent tool, awesome support always.

bilbo6209

etippelt unfortunatly no it isnt an MSI  I wish it was.

TD
The error is a WSH (vbs) error Permission denied
script: {path to script}\dms_licnese.vbs
line:45
charactor: 6
error: Permission Denied
code: 800A0046
source: MS VBScript runtime

I get this same error if I run the script as a limited user, but if I manually run the script as system (using PSExec) the script runs perfect
Line 45 is "objFSO.CopyFile (strScriptFileDirectory & "\user.config"), (strAppDataFolder & "\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3\2.6.141.0\user.config"), True"

I am calling the VBS using this (to allow for a dirty log of completion)
               strlicense   = strcat (strhome,"dms_license.vbs")
   blnlicense = Runwait(strlicense,"")
   LogMessage(strLogFile, strLogSize, StrCat(strSection, " - Install of DMS License ended with exit code of = ",blnlicense ))   

Deana

Please answer: Are you using a compiled WinBatch script? If so what Manifest settings did you choose when you compiled?
Deana F.
Technical Support
Wilson WindowWare Inc.

bilbo6209

Sorry forgot that part :)

Yes it is a compiled script and I appologize I am not certian what you mean by "Manifest settings" but Im hoping this helps
when I click Compile > Options > Settings under UAC setttings Requested Execution Level is set to Highest Availble, I have tried this and asInvoker both generate the same error.

td

One final note.  The WinBatch RunWait function use the Win32 API function CreateProcess to start external applications.  There are two exceptions to this but neither of them apply in this case.  The first two sentences of the MSFT documentation for the CreateProcess function states, "Creates a new process and its primary thread. The new process runs in the security context of the calling process." Bold type added for emphasis.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

Deana

I recommend using the WinBatch code Tony posted. Then you can avoid using the VBS script all together.
Deana F.
Technical Support
Wilson WindowWare Inc.

td

It is certainly worth a try but the available evidence certainly suggests that the code would have the same error outcome as a vbs script launched from WinBatch. 
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

etippelt

Do you use roaming profiles? If not, you can easily cycle through the users and install the files directly even if deploying as a system process.
If you do use roaming profiles, then there is another approach you could try. Wrap the main installer in an MSI. Run the main installer before InstallInitialize in the Execute sequence. Add the main executable from the installation to the RemoveFiles table so it gets deleted. In the main MSI, create a User feature and a Main subfeature. Put the main executable and an advertised shortcut to it, in the Main subfeature.  Put the necessary files for deployment to the user profile into a single component in the User feature and add a registry key path (make one up) to the same component.  When the user fires off the advertised shortcut, the advertised entry points will be checked up the feature tree and the user feature will consequently be repaired.  Remember to consider the uninstall process and build this into the MSI with appropriate conditions, etc.

It's not ideal but I cannot see any objection to this approach in the list of stupid ideas your client has so far enumerated. 

You might also point out that Active Setup runs ONCE per user, so although there might be a tiny delay the first time a user logs on after the app is installed, it will not impact future logons.
Using Winbatch since 1995. Excellent tool, awesome support always.

bilbo6209

Hmmm TD I think we are getting close but I am getting an error now that im not sure what it is trying to tell me....
The code I am now using is (yours with a couple tweaks, == in place of =, and adding a : inplace of a , on one line)
objWshShell = CreateObject("WScript.Shell")
objFSO = CreateObject("Scripting.FileSystemObject")
strScriptFileDirectory = DirScript()

strAllUsersDesktopPath = objWshShell.RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\Common Desktop")
; Attempts to configure Windows 2000/XP paths.
strUserProfilesMainFolder = StrSub(strAllUsersDesktopPath,1,StrIndex(strAllUsersDesktopPath, "\All Users", 1, @Fwdscan))
If strUserProfilesMainFolder == "" then   
; Windows 2000/XP paths are not valid, so attempting to configure Windows Vista/7 paths.   
strUserProfilesMainFolder = StrSub(strAllUsersDesktopPath,1,StrIndex(strAllUsersDesktopPath, "\Public", 1, @Fwdscan))
endif
objFolder = objFSO.GetFolder(strUserProfilesMainFolder).Subfolders
ForEach objFolderItem in objFolder       
strPath = objFolderItem.Path   
If strPath  == (strUserProfilesMainFolder : "LocalService") Then     
;This one is not a valid user folder, so we ignore it.   
Else     
If strPath  == (strUserProfilesMainFolder : "NetworkService") Then         
;This one is not a valid user folder, so we ignore it.     
Else         
If strPath  == (strUserProfilesMainFolder : "Public") Then           
;This one is not a valid user folder, so we ignore it.         
Else           
;The following example may not be valid for all directories in the user profile folder - it's here to help illustrate how to determine between an XP and a 7 directory structure in a key location.           
If objFSO.FolderExists(:strPath  : "\Application Data") Then               
strAppDataFolder = strPath  : "\Application Data"           
Else               
strAppDataFolder = strPath  : "\AppData\Local"           
EndIf           
If !objFSO.FolderExists(:strAppDataFolder : "\3M") Then               
objFSO.CreateFolder(:strAppDataFolder : "\3M")           
EndIf           
If !objFSO.FolderExists(:strAppDataFolder : "\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3") Then               
objFSO.CreateFolder( :strAppDataFolder : "\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3")           
EndIf           
If !objFSO.FolderExists(:strAppDataFolder : "\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3\2.6.141.0") Then               
objFSO.CreateFolder(:strAppDataFolder : "\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3\2.6.141.0")           
EndIf           
If objFSO.FileExists(:strScriptFileDirectory : "\user.config") Then               
objFSO.CopyFile(:strScriptFileDirectory : "\user.config" : strAppDataFolder : "\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3\2.6.141.0\user.config", @True)           
EndIf         
EndIf     
EndIf   
EndIf
Next

I am getting a winbatch error on the line
objFSO.CopyFile(:strScriptFileDirectory : "\user.config" : strAppDataFolder : "\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3\2.6.141.0\user.config", @True)         
Error: WBT - DMS.exe
Error {path to script}\dms.exe
1261: Ole: Exception


I am sorrry if this is a simple question, I am fairly new to Winbatch,

Bill

Deana

It appears you edited the objFSO.CopyFile line and replaced the comma with a colon. The CopyFile method actually takes up to three parameters and those parameters need to be delimited with a comma.

http://msdn.microsoft.com/en-us/library/e1wf9e7w(v=vs.84).aspx

Should read something like:
Code (winbatch) Select

objFSO.CopyFile(:strScriptFileDirectory : "\user.config", strAppDataFolder : "\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3\2.6.141.0\user.config", @True)


When you get an OLE exception error 1261, make sure to click on the [More Error Info] button to retrieve extended error details.

Please note that Tony stated the you will likely run into the same type of error (access denied) you were getting from your .VBS script. You will need to most like address the access denied issue before proceeding. I recommend paying very close attention to the account that is used to launch the script.

Deana F.
Technical Support
Wilson WindowWare Inc.

bilbo6209

Thank you Deana,

The script errored out with the comma (I will run it again in a bit and see what the exact error was, my VM is tied up with another install issue currently)....

As far as the access denied, I am running this using PS Exec running the compiled Winbatch exe as the system account, you dont get a higher priv account than that! The account has the required perms to install the application, and to modify global certs on the PC, the only part of the script that is erroring is adding 1 file to the user profiles.

Bill

td

Actually, the system account is not an über account. It has restrictions.

Since you are now using psexec to launch your script on the remote system, you should not have a permission issue, however.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

etippelt

If your environment is set up to use roaming profiles or the user folders are redirected to a server share then you are not going to be able to"see" the user folders as they are not on the local hard disk but elsewhere where the system account has no rights.
Using Winbatch since 1995. Excellent tool, awesome support always.

td

Since the OP has been able to launch the compiled WinBatch script using psexec and was able to add files using a VB script, it can be assumed that he is not using a share.  But it is true that the system account does not have access to network resources and if any of the targeted user profile destinations do exist on a share, the script will fail.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

bilbo6209

Correct we are not using roaming profiles.

All files are copied to the C: drive, basicly the script adds in 2 certs (it calls A BAT file to do this) to allow the silent install of 2 unsigned drivers, then the script kicks off the install (admin rights are required), then it attempts to copy 1 file to each users appdata/local folder (after creating a long ugly named folder) this is where I am still getting denied.

Deana, I made the modifications you listed and now I am getting an 1702: ObjectType: Unsupported Variant-Type error
objFolder = objFSO.GetFolder(strUserProfilesMainFolder).Subfolders
ForEach objFolderItem in objFolder       
strPath = objFolderItem.Path   
If strPath  == (strUserProfilesMainFolder : "LocalService") Then     
;This one is not a valid user folder, so we ignore it.   
Else     
If strPath  == (strUserProfilesMainFolder : "NetworkService") Then         
;This one is not a valid user folder, so we ignore it.     
Else         
If strPath  == (strUserProfilesMainFolder : "Public") Then           
;This one is not a valid user folder, so we ignore it.         
Else           
;The following example may not be valid for all directories in the user profile folder - it's here to help illustrate how to determine between an XP and a 7 directory structure in a key location.           
If objFSO.FolderExists(:strPath  : "\Application Data") Then               
strAppDataFolder = strPath  : "\Application Data"           
Else               
strAppDataFolder = strPath  : "\AppData\Local"           
EndIf           
If !objFSO.FolderExists(:strAppDataFolder : "\3M") Then               
objFSO.CreateFolder(:strAppDataFolder : "\3M")           
EndIf           
If !objFSO.FolderExists(:strAppDataFolder : "\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3") Then               
objFSO.CreateFolder( :strAppDataFolder : "\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3")           
EndIf           
If !objFSO.FolderExists(:strAppDataFolder : "\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3\2.6.141.0") Then               
objFSO.CreateFolder(:strAppDataFolder : "\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3\2.6.141.0")           
EndIf

Deana

You mention you are getting the error 1702: ObjectType: Unsupported Variant-Type error . Please post the exact line of code. DebugTrace output might be helpful.
Deana F.
Technical Support
Wilson WindowWare Inc.

bilbo6209

the exact line of code is the one you supplied
objFSO.CopyFile(:strScriptFileDirectory : "\user.config", strAppDataFolder : "\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3\2.6.141.0\user.config", @True)

debug runs through without any errors

         

td

The colon (: ) is an overloaded operator in WIL.  When ever you use it for string concatenation to generate a parameter during a object method call, you need to presage it with the type specifier interpretation of the colon operator.  So add a colon just pass the first comma:

Code (winbatch) Select
objFSO.CopyFile(:strScriptFileDirectory : "\user.config", :strAppDataFolder : "\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3\2.6.141.0\user.config", @True)

The colon tells the interpreter to takes it's best guess at the type and interpret everything that follows as part of the parameter's value. 

Also note that the original script had a comment stating that the it had not been tested an therefore was guaranteed to contain bugs. ::)
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

bilbo6209

Thank you again for all your help TD,

Im now getting the OLE 1261 error pointing to the line
objFSO.CopyFile(:strScriptFileDirectory : "\user.config", :strAppDataFolder : "\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3\2.6.141.0\user.config", @True)

The More error info button is greyed out so I dont have any idea about this error. (silly Noobs  ::))

Bill

td

WinBatch always checks for addition error information when an object throws an exception but some objects are not forthcoming.

I am not sure why you are getting an exception here but one possibility is that the source path+file has an extra backslash character (\ ) if you are using DirScript to assign the strScriptFileDirectory variable.  Try changing the source parameter from ':strScriptFileDirectory : "\user.config"' to ':strScriptFileDirectory : "user.config"'

If that does not work, try substituting the WIL FileCopy function for your objFSO.CopyFile method call.  If nothing else, it should provide you with a system Win32 error number. (Don't forget to remove the leading colons from the parameters when using FileCopy and change the @True to @False, as well.)
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

bilbo6209

HMM ok we're getting closer, The OLE error was due to the file already existing, I will add in a check for the file.

I am now getting a Winbatch error
3357: End Error: No match found
NEXT

I spent a good portion of the day yesterday looking at this, I dont see anything that should be an issue, but the script is confused by the loop and next.

here is the code so far.
objWshShell = CreateObject("WScript.Shell")
objFSO = CreateObject("Scripting.FileSystemObject")
strScriptFileDirectory = DirScript()

strAllUsersDesktopPath = objWshShell.RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\Common Desktop")
; Attempts to configure Windows 2000/XP paths.
strUserProfilesMainFolder = StrSub(strAllUsersDesktopPath,1,StrIndex(strAllUsersDesktopPath, "\All Users", 1, @Fwdscan))
If strUserProfilesMainFolder == "" Then
   ; Windows 2000/XP paths are not valid, so attempting to configure Windows Vista/7 paths.   
   strUserProfilesMainFolder = StrSub(strAllUsersDesktopPath,1,StrIndex(strAllUsersDesktopPath, "\Public", 1, @Fwdscan))
End If

objFolder = objFSO.GetFolder(strUserProfilesMainFolder).Subfolders
ForEach objFolderItem in objFolder
   strPath = objFolderItem.Path   
   If strPath  == (strUserProfilesMainFolder : "LocalService") Then
   ;This one is not a valid user folder, so we ignore it.   
   Else     
      If strPath  == (strUserProfilesMainFolder : "NetworkService") Then         
      ;This one is not a valid user folder, so we ignore it.     
      Else         
         If strPath  == (strUserProfilesMainFolder : "Public") Then           
         ;This one is not a valid user folder, so we ignore it.         
         Else           
            If objFSO.FolderExists(:strPath  : "\Application Data") Then               
            strAppDataFolder = strPath  : "\Application Data"           
            Else               
            strAppDataFolder = strPath  : "\AppData\Local"           
            EndIf           
            If !objFSO.FolderExists(:strAppDataFolder : "\3M") Then               
            objFSO.CreateFolder(:strAppDataFolder : "\3M")           
            EndIf           
            If !objFSO.FolderExists(:strAppDataFolder : "\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3") Then               
            objFSO.CreateFolder( :strAppDataFolder : "\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3")           
            EndIf           
            If !objFSO.FolderExists(:strAppDataFolder : "\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3\2.6.141.0") Then               
            objFSO.CreateFolder(:strAppDataFolder : "\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3\2.6.141.0")           
            EndIf           
            If objFSO.FileExists(:strScriptFileDirectory : "\user.config") Then               
            objFSO.CopyFile(:strScriptFileDirectory : "\user.config", strAppDataFolder : "\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3\2.6.141.0\user.config", @True) 
            EndIf         
         EndIf     
      EndIf   
   EndIf
   Next

td

You have a space between the 'end and the 'if' in your first 'Endif'.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

bilbo6209

TD Thank you again for your help!!! But I am still getting a Winbatch error of 3357: end Error: No match found

here is the latest code
objWshShell = CreateObject("WScript.Shell")
objFSO = CreateObject("Scripting.FileSystemObject")
strScriptFileDirectory = DirScript()

strAllUsersDesktopPath = objWshShell.RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\Common Desktop")
; Attempts to configure Windows 2000/XP paths.
strUserProfilesMainFolder = StrSub(strAllUsersDesktopPath,1,StrIndex(strAllUsersDesktopPath, "\All Users", 1, @Fwdscan))
If strUserProfilesMainFolder == "" Then
   ; Windows 2000/XP paths are not valid, so attempting to configure Windows Vista/7 paths.   
   strUserProfilesMainFolder = StrSub(strAllUsersDesktopPath,1,StrIndex(strAllUsersDesktopPath, "\Public", 1, @Fwdscan))
EndIf

objFolder = objFSO.GetFolder(strUserProfilesMainFolder).Subfolders
ForEach objFolderItem in objFolder
   strPath = objFolderItem.Path   
   If strPath  == (strUserProfilesMainFolder : "LocalService") Then
   ;This one is not a valid user folder, so we ignore it.   
   Else     
      If strPath  == (strUserProfilesMainFolder : "NetworkService") Then         
      ;This one is not a valid user folder, so we ignore it.     
      Else         
         If strPath  == (strUserProfilesMainFolder : "Public") Then           
         ;This one is not a valid user folder, so we ignore it.         
         Else           
            If objFSO.FolderExists(:strPath  : "\Application Data") Then               
            strAppDataFolder = strPath  : "\Application Data"           
            Else               
            strAppDataFolder = strPath  : "\AppData\Local"           
            EndIf           
            If !objFSO.FolderExists(:strAppDataFolder : "\3M") Then               
            objFSO.CreateFolder(:strAppDataFolder : "\3M")           
            EndIf           
            If !objFSO.FolderExists(:strAppDataFolder : "\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3") Then               
            objFSO.CreateFolder( :strAppDataFolder : "\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3")           
            EndIf           
            If !objFSO.FolderExists(:strAppDataFolder : "\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3\2.6.141.0") Then               
            objFSO.CreateFolder(:strAppDataFolder : "\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3\2.6.141.0")           
            EndIf           
            If objFSO.FileExists(:strScriptFileDirectory : "user.config") Then 
            strsrcfile = strcat( strhome, "user.config")
            strdstfile = strcat( strAppDataFolder,"\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3\2.6.141.0","\user.config")
            pause (  strsrcfile, strdstfile)
                     
            ;objFSO.CopyFile(:strScriptFileDirectory : "user.config", :strAppDataFolder : "\3M\Detection_Management_Soft_Url_fs4yyhoqykgxwomvch51nkqcuxxcztd3\2.6.141.0\user.config", @True)         
            if  !fileexist(strdstfile)then
            pause ("file not exist", "file not exist")
            filecopy (strsrcfile,strdstfile, @FALSE)
            EndIf         
         EndIf     
      EndIf   
   EndIf
Next

OH the OLE error was due to teh file existing already, that is why there is the check in the script now for if the file exists.

Bill

td

That's because you are now missing an 'Endif' before the 'Next'.  If you use proper indentation, it is much easier to see unbalanced structures.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade