How to add a mapped network drive via VBS? - windows

I'm having some issues with my vbs script. It will add only the F drive and not add the G driver after it. What am I doing wrong?
'## This is for network drives
Set objNetwork = CreateObject("WScript.Network")
objNetwork.RemoveNetworkDrive "F:", True, True
'## for adding
Set objNetwork = CreateObject("WScript.Network")
objNetwork.MapNetworkDrive "F:" , "\\myserver\share1"
objNetwork.MapNetworkDrive "G:" , "\\myserver\share2"

MapDrive.vbs
VBScript to Map a Drive letter to a network file share (non-persistent).
This script is designed for reliability above speed, so it will reconnect at every login.
It accounts for 'remembered' connections including those to a file share that no longer exists or which is off-line.
This is a good approach for machines that are not always connected to the domain e.g. Laptops.
Windows XP will not map a 'remembered' connection to a different server unless you first unmap & unremember the existing connection, this applies even if the old connection path is currently disconnected.
For each drive letter there are several possible states, that may have to be dealt with by the script:
- Remembered (persistent connection) / Not Remembered
- Already Connected / Connected to the wrong network share / Not Connected.
This script will remove any existing Drive Map, before connecting to the correct file share.
' Map a network drive
' Usage
' cscript MapDrive.vbs drive fileshare //NoLogo
' cscript MapDrive.vbs H: \\MyServer\MyShare //NoLogo
'
' This script will remove any existing drive map to the same drive letter
' including persistent or remembered connections (Q303209)
Option Explicit
Dim objNetwork, objDrives, objReg, i
Dim strLocalDrive, strRemoteShare, strShareConnected, strMessage
Dim bolFoundExisting, bolFoundRemembered
Const HKCU = &H80000001
' Check both parameters have been passed
If WScript.Arguments.Count < 2 Then
wscript.echo "Usage: cscript MapDrive.vbs drive fileshare //NoLogo"
WScript.Quit(1)
End If
strLocalDrive = UCase(Left(WScript.Arguments.Item(0), 2))
strRemoteShare = WScript.Arguments.Item(1)
bolFoundExisting = False
' Check parameters passed make sense
If Right(strLocalDrive, 1) <> ":" OR Left(strRemoteShare, 2) <> "\\" Then
wscript.echo "Usage: cscript MapDrive.vbs drive fileshare //NoLogo"
WScript.Quit(1)
End If
wscript.echo " - Mapping: " + strLocalDrive + " to " + strRemoteShare
Set objNetwork = WScript.CreateObject("WScript.Network")
' Loop through the network drive connections and disconnect any that match strLocalDrive
Set objDrives = objNetwork.EnumNetworkDrives
If objDrives.Count > 0 Then
For i = 0 To objDrives.Count-1 Step 2
If objDrives.Item(i) = strLocalDrive Then
strShareConnected = objDrives.Item(i+1)
objNetwork.RemoveNetworkDrive strLocalDrive, True, True
i=objDrives.Count-1
bolFoundExisting = True
End If
Next
End If
' If there's a remembered location (persistent mapping) delete the associated HKCU registry key
If bolFoundExisting <> True Then
Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
objReg.GetStringValue HKCU, "Network\" & Left(strLocalDrive, 1), "RemotePath", strShareConnected
If strShareConnected <> "" Then
objReg.DeleteKey HKCU, "Network\" & Left(strLocalDrive, 1)
Set objReg = Nothing
bolFoundRemembered = True
End If
End If
'Now actually do the drive map (not persistent)
Err.Clear
On Error Resume Next
objNetwork.MapNetworkDrive strLocalDrive, strRemoteShare, False
'Error traps
If Err <> 0 Then
Select Case Err.Number
Case -2147023694
'Persistent connection so try a second time
On Error Goto 0
objNetwork.RemoveNetworkDrive strLocalDrive, True, True
objNetwork.MapNetworkDrive strLocalDrive, strRemoteShare, False
WScript.Echo "Second attempt to map drive " & strLocalDrive & " to " & strRemoteShare
Case Else
On Error GoTo 0
WScript.Echo " - ERROR: Failed to map drive " & strLocalDrive & " to " & strRemoteShare
End Select
Err.Clear
End If
Set objNetwork = Nothing
From http://ss64.com/vb/syntax-mapdrive.html

I've done this before like this:
dim objNet, strLocal, strPath, fso
Set fso = WScript.CreateObject("Scripting.FileSystemObject")
Set objNet = WScript.CreateObject("WScript.Network")
'Name the drives and their paths
strLocal = Array("H:","M:")
strPath = Array("\\Full\Path\Number1", _
\\Full\Path\Number2")
'Loop to check if they are mapped, map it if they are not
For i = LBound(strLocal) To UBound(strLocal)
If fso.FolderExists(strLocal(i)) = True Then
wscript.echo(strLocal(i) & " Mapped")
Else
objNet.MapNetworkDrive strLocal(i), strPath(i), False
wscript.echo(strLocal(i) & " Re-mapped")
End If
Next
'Wrap up the script
WScript.Echo("")
WScript.Echo("Mapping Completed")
WScript.Sleep(2000)
'Keep the command prompt open long enough to see that it is completed
Set fso=Nothing
Set objNet=Nothing
Essentially, it checks to see if the drive is mapped already, and if not, then it will map it. I added this to my startup folder because I keep getting my corp network drives to lose connection when I reboot.

Related

VBScript MapNetworkDrive Error Handling

I am attempting to write a small script in VBScript just purely for my home use, which is run prior to a scheduled backup in Macrium Reflect.
I am stuck on one seemingly small issue and that is error handling when the Network Drive is physically disconnected, i.e. the cable is not attached.
At the moment the script check to see if the Drive is already attached, if the drive is not attached then a message is displayed telling the user to connect the cable and press YES.
Now, all things being well the user would have connected the cable as asked and then pressed the YES button but I want to catch the times when YES was pressed before attaching the drive's cable.
Within the code there's an 'On Error Resume Next' which masks this eventuality, so I comment out this line & indeed I get an Error 'The Network Path Was Not Found' on line 40:
objNetwork.MapNetworkDrive strDriveLetter, strRemotePath, _
I want to use this caught error to display an alert to the user that the drive has not yet been connected, please connect and retry & KEEP RETRYING until the drive is actually connected.
My problem is I cannot seem to find where to add any error handling code to display this message.
Here's my code:
Option Explicit
Dim strDriveLetter, strRemotePath, strUser, strPassword, strProfile, strName, objNetwork, objShell, CheckDrive, AlreadyConnected, intDrive
' The section sets the variables.
strDriveLetter = "X:"
strRemotePath = "\\192.168.1.1\shared"
strUser = "user"
strPassword = "password"
strProfile = "true"
strName = "Backup Drive"
' This sections creates two objects:
' objShell and objNetwork and counts the drives
Set objShell = CreateObject("WScript.Shell")
Set objNetwork = CreateObject("WScript.Network")
Set CheckDrive = objNetwork.EnumNetworkDrives()
' This section deals with a For ... Next loop
' See how it compares the enumerated drive letters
' with strDriveLetter
On Error Resume Next
AlreadyConnected = False
For intDrive = 0 To CheckDrive.Count - 1 Step 2
If CheckDrive.Item(intDrive) =strDriveLetter _
Then AlreadyConnected = True
Next
If AlreadyConnected = False Then
Dim result
result = MsgBox("A Backup Is Now Due But The Drive Is Not Connected." & vbNewLine & vbNewLine & "Please Connect The Drive & Press YES To Continue." & vbNewLine & vbNewLine & "If You Wish To Postpone Backup Then Press NO Now.", 4 + 32, "BACKUP DRIVE NOT CONNECTED")
If result = 7 Then
WScript.Quit
Else
Call MapDRV
End If
Sub MapDRV()
Set objNetwork = WScript.CreateObject("WScript.Network")
objNetwork.MapNetworkDrive strDriveLetter, strRemotePath, _
strProfile, strUser, strPassword
Set objShell = CreateObject("Shell.Application")
objShell.NameSpace(strDriveLetter).Self.Name = strName
End Sub
WScript.Quit
The error handling code is something along these lines:
If Err.Number <> 0 Then
'error handling:
'ALERT USER HERE
Err.Clear
End If
Any help would be appreciated
Err Object (VBScript) reference does not give useful guide. You need to trap an error or success separate for every run-time error prone action.
Common rule (best practice): keep error handling disabled via On Error GoTo 0 and enable it only for suspected actions.
For instance, there could me more than one reason why MapNetworkDrive method could fail (server off-line, user blocked, wrong/changed password etc.):
Sub MapDRV
Dim errResult
Set objNetwork = WScript.CreateObject("WScript.Network")
errResult = ""
On Error Resume Next
objNetwork.MapNetworkDrive strDriveLetter, strRemotePath _
, strProfile, strUser, strPassword
If Err.Number = 0 Then
On Error GoTo 0
Set objShell = CreateObject("Shell.Application")
objShell.NameSpace(strDriveLetter).Self.Name = strName
Else
errResult = Err.Number & " 0x" & Hex(Err.Number) & " " & Err.Source
errResult = errResult & vbNewLine & Err.Description
On Error GoTo 0
MsgBox errResult, vbOKOnly + vbCritical, "Error occurred"
End If
End Sub
The whole script then could look as follows:
Option Explicit
On Error GoTo 0
Dim strResult: strResult = Wscript.ScriptName
Dim strDriveLetter, strRemotePath, strUser, strPassword, strProfile , strName _
, objNetwork, objShell, CheckDrive, AlreadyConnected, intDrive
' The section sets the variables.
strDriveLetter = "X:"
strRemotePath = "\\192.168.1.1\shared"
strUser = "user"
strPassword = "password"
strProfile = "true"
strName = "Backup Drive"
' This sections creates two objects:
' objShell and objNetwork and counts the drives
Set objShell = CreateObject("WScript.Shell")
Set objNetwork = CreateObject("WScript.Network")
' This section deals with a For ... Next loop
' See how it compares the enumerated drive letters with strDriveLetter
Dim result, toShare
AlreadyConnected = False
Do While AlreadyConnected = False
strResult = strResult & vbNewLine & "--- new check"
AlreadyConnected = False
Set CheckDrive = objNetwork.EnumNetworkDrives()
For intDrive = 0 To CheckDrive.Count - 1 Step 2
If CheckDrive.Item(intDrive) = strDriveLetter Then
AlreadyConnected = True
toShare = CheckDrive.Item(intDrive + 1)
End If
strResult = strResult & vbNewLine & CheckDrive.Item(intDrive)
strResult = strResult & vbTab & CheckDrive.Item(intDrive + 1)
Next
If AlreadyConnected Then Exit Do
result = MsgBox("A Backup Is Now Due But The Drive Is Not Connected." _
& vbNewLine & vbNewLine & "If you wish to ..." _
& vbNewLine & vbTab & "... postpone backup then press ABORT." _
& vbNewLine & vbTab & "... backup to " & strRemotePath & " then press RETRY." _
& vbNewLine & "Otherwise, please connect the drive & press IGNORE to continue." _
, vbAbortRetryIgnore + vbQuestion, "BACKUP DRIVE NOT CONNECTED")
Select Case result
Case vbAbort
Call scriptQuit
Case vbRetry
Call MapDRV
Case Else
' The Case Else clause is not required
End Select
Loop
strResult = strResult & vbNewLine & "copy here to " & toShare
Sub MapDRV
' no need to redefine: WshNetwork Object is already defined
' Set objNetwork = WScript.CreateObject("WScript.Network")
Dim errResult
On Error Resume Next
objNetwork.MapNetworkDrive strDriveLetter, strRemotePath _
, strProfile, strUser, strPassword
If Err.Number = 0 Then
On Error GoTo 0
Set objShell = CreateObject("Shell.Application")
objShell.NameSpace(strDriveLetter).Self.Name = strName
Else
errResult = Err.Number & " 0x" & Hex(Err.Number) & " " & Err.Source
errResult = errResult & vbNewLine & Err.Description
On Error GoTo 0
MsgBox errResult, vbOKOnly + vbCritical, "Error occurred"
strResult = strResult & vbNewLine & vbNewLine & errResult
End If
End Sub
Call scriptQuit
Sub scriptQuit
Wscript.Echo strResult
Wscript.Quit
End Sub
Please note that strResult variable is there merely for debugging purposes to see next output:
==> cscript D:\VB_scripts\SO\37776762.vbs
37776762.vbs
--- new check
Y: \\S-PC\VB_scripts_help
-2147024843 0x80070035 WSHNetwork.MapNetworkDrive
The network path was not found.
--- new check
Y: \\S-PC\VB_scripts_help
--- new check
Y: \\S-PC\VB_scripts_help
X: \\S-PC\test
copy here to \\S-PC\test
==>
Above output corresponds to next actions:
run script
1st --- new check found Y: mapped disk; then invoked Retry action failed (network path was not found);
2nd --- new check found Y: mapped disk again; then mapped disk X: manually and then invoked Ignore action;
3rd --- new check found Y: and X: mapped disks;
Do While loop exited and script continues to next action.
For completeness, following output shows invoked Abort action:
==> net use x: /delete
x: was deleted successfully.
==> cscript D:\VB_scripts\SO\37776762.vbs
37776762.vbs
--- new check
Y: \\S-PC\VB_scripts_help
==>

How Can I Determine the Size of the 'My Documents' Folder for every user on a local machine using VBScript?

I am at my wits end into this. Either I am doing it the wrong way or it is not possible.
I need a vb script for the following scenario:
The script is to run on multiple Windows 7 machines (32-Bit & 64-Bit alike).
These are shared workstation i.e. different users login to these machines from time to time.
The objective of this script is to traverse through each User Profile folder and get the size of the 'My Documents' folder within each User Profile folder. This information is to be written to a .CSV file located at C:\Temp directory on the machine.
This script would be pushed to all workstations from SCCM. It would be configured to execute with System Rights
I tried the script detailed at:
http://blogs.technet.com/b/heyscriptingguy/archive/2005/03/31/how-can-i-determine-the-size-of-the-my-documents-folder.aspx
Const MY_DOCUMENTS = &H5&
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.Namespace(MY_DOCUMENTS)
Set objFolderItem = objFolder.Self
strPath = objFolderItem.Path
Set objFolder = objFSO.GetFolder(strPath)
Wscript.Echo objFolder.Size
The Wscript.Echo objFolder.Size command in the script returned the value as '0' (zero) for the current logged on user. Although the actual size was like 30 MB or so.
I then tried the script at:
http://www.experts-exchange.com/Programming/Languages/Visual_Basic/VB_Script/Q_27869829.html
This script returns the correct value but only for the current logged-on user.
Const blnShowErrors = False
' Set up filesystem object for usage
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objShell = CreateObject("WScript.Shell")
' Display desired folder sizes
Wscript.Echo "MyDocuments : " & FormatSize(FindFiles(objFSO.GetFolder(objShell.SpecialFolders("MyDocuments"))))
' Recursively tally the size of all files under a folder
' Protect against folders or files that are not accessible
Function FindFiles(objFolder)
On Error Resume Next
' List files
For Each objFile In objFolder.Files
On Error Resume Next
If Err.Number <> 0 Then ShowError "FindFiles:01", objFolder.Path
On Error Resume Next
FindFiles = FindFiles + objFile.Size
If Err.Number <> 0 Then ShowError "FindFiles:02", objFile.Path
Next
If Err.Number = 0 Then
' Recursively drill down into subfolder
For Each objSubFolder In objFolder.SubFolders
On Error Resume Next
If Err.Number <> 0 Then ShowError "FindFiles:04", objFolder.Path
FindFiles = FindFiles + FindFiles(objSubFolder)
If Err.Number <> 0 Then ShowError "FindFiles:05", objSubFolder.Path
Next
Else
ShowError "FindFiles:03", objFolder.Path
End If
End Function
' Function to format a number into typical size scales
Function FormatSize(iSize)
aLabel = Array("bytes", "KB", "MB", "GB", "TB")
For i = 0 to 4
If iSize > 1024 Then iSize = iSize / 1024 Else Exit For End If
Next
FormatSize = Round(iSize, 2) & " " & aLabel(i)
End Function
Sub ShowError(strLocation, strMessage)
If blnShowErrors Then
WScript.StdErr.WriteLine "==> ERROR at [" & strLocation & "]"
WScript.StdErr.WriteLine " Number:[" & Err.Number & "], Source:[" & Err.Source & "], Desc:[" & Err.Description & "]"
WScript.StdErr.WriteLine " " & strMessage
Err.Clear
End If
End Sub
The only part pending, is to achieve this for the 'My Documents' folder within each of the other User Profile folders.
Is this possible?
Please help.

VBS To Event Log

I have a script that I am currently using to check when that network goes up or down. Its writing to a pinglog.txt .
For the life of me I can not figure out how to get it to write to the event log when the network goes down. Where it says:
Call logme(Time & " - " & machine & " is not responding to ping, CALL FOR
HELP!!!!",strLogFile)
Thats what I need to write to the Event Log "Machine is not repsonding to ping, CALL FOR HELP!!!!
'Ping multiple computers and log when one doesn't respond.
'################### Configuration #######################
'Enter the IPs or machine names on the line below separated by a semicolon
strMachines = "4.2.2.2;8.8.8.8;8.8.4.4"
'Make sure that this log file exists, if not, the script will fail.
strLogFile = "c:\logs\pinglog.txt"
'################### End Configuration ###################
'The default application for .vbs is wscript. If you double-click on the script,
'this little routine will capture it, and run it in a command shell with cscript.
If Right(WScript.FullName,Len(WScript.FullName) - Len(WScript.Path)) <> "\cscript.exe" Then
Set objWMIService = GetObject("winmgmts: {impersonationLevel=impersonate}!\\.\root\cimv2")
Set objStartup = objWMIService.Get("Win32_ProcessStartup")
Set objConfig = objStartup.SpawnInstance_
Set objProcess = GetObject("winmgmts:root\cimv2:Win32_Process")
objProcess.Create WScript.Path + "\cscript.exe """ + WScript.ScriptFullName + """", Null, objConfig, intProcessID
WScript.Quit
End If
Const ForAppending = 8
Const ForReading = 1
Const ForWriting = 2
Set objFSO = CreateObject("Scripting.FileSystemObject")
If objFSO.FileExists(strLogFile) Then
Set objFolder = objFSO.GetFile(strLogFile)
Else
Wscript.Echo "Log file does not exist. Please create " & strLogFile
WScript.Quit
End If
aMachines = Split(strMachines, ";")
Do While True
For Each machine In aMachines
Set objPing = GetObject("winmgmts:{impersonationLevel=impersonate}")._
ExecQuery("select * from Win32_PingStatus where address = '"_
& machine & "'")
For Each objStatus In objPing
If IsNull(objStatus.StatusCode) Or objStatus.StatusCode<>0 Then
Call logme(Time & " - " & machine & " is not responding to ping, CALL FOR
HELP!!!!",strLogFile)
Else
WScript.Echo(Time & " + " & machine & " is responding to ping, we are good")
End If
Next
Next
WScript.Sleep 5000
Loop
Sub logme(message,logfile)
Set objTextFile = objFSO.OpenTextFile(logfile, ForAppending, True)
objtextfile.WriteLine(message)
WScript.Echo(message)
objTextFile.Close
End Sub
Sorry about the spacing in the code. Thanks for the help
Use the WshShell object:
object.LogEvent(intType, strMessage [,strTarget])
object WshShell object.
intType Integer value representing the event type.
strMessage String value containing the log entry text.
strTarget Optional. String value indicating the name of the computer
system where the event log is stored (the default is the local
computer system). Applies to Windows NT/2000 only.
Like so:
Option Explicit
Dim shl
Set shl = CreateObject("WScript.Shell")
Call shl.LogEvent(1,"Some Error Message")
Set shl = Nothing
WScript.Quit
The first argument to LogEvent is an event type:
0 SUCCESS
1 ERROR
2 WARNING
4 INFORMATION
8 AUDIT_SUCCESS
16 AUDIT_FAILURE
EDIT: more detail
Replace your entire 'logme' sub-routine with this
Sub logme(t,m)
Dim shl
Set shl = CreateObject("WScript.Shell")
Call shl.LogEvent(t,m)
Set shl = Nothing
End Sub
Then change this line:
Call logme(Time & " - " & machine & " is not responding to ping, CALL FOR HELP!!!!",strLogFile)
To:
Call logme(1, machine & " is not responding to ping, CALL FOR HELP!!!!")

Open another user registry settings

I want to write a application that writes to all users on a local machine a specified key (eg: i want set the location for IE Favorites for all users to the same folder)
PS
anybody used these functions?
LoadUserProfile
RegOpenCurrentUser
CreateProcessAsUser
I've done this many times. The idea is to update the currently logged on user's HKCU (that's easy enough). Then you must enumerate every profile on the system and find their ntuser.dat file (that's easy enough too).
With the ntuser.dat file found, you load it into a temporary key in the HKLM hive (I usually use 'HKLM\TempHive'. Then edit away.
If there is more than 1 user logged on, their profile will be loaded under HKEY_USERS, by their SID. Simply update that location.
To modify the setting for any new users, simply modify the appropriate key under HKEY_USERS.DEFAULT, OR use the Delphi code below which will do this by loading the Default Users's HKCU registry hive (stored in ntuser.dat).
UPDATE: I found my Delphi code that demonstrates how to update the HKCU hives of users that are not logged onto the system.
This requires Russell Libby's 'Privilege' component, which is available here.
//NOTE: sPathToUserHive is the full path to the users "ntuser.dat" file.
//
procedure LoadUserHive(sPathToUserHive: string);
var
MyReg: TRegistry;
UserPriv: TUserPrivileges;
begin
UserPriv := TUserPrivileges.Create;
try
with UserPriv do
begin
if HoldsPrivilege(SE_BACKUP_NAME) and HoldsPrivilege(SE_RESTORE_NAME) then
begin
PrivilegeByName(SE_BACKUP_NAME).Enabled := True;
PrivilegeByName(SE_RESTORE_NAME).Enabled := True;
MyReg := TRegistry.Create;
try
MyReg.RootKey := HKEY_LOCAL_MACHINE;
MyReg.UnLoadKey('TEMP_HIVE'); //unload hive to ensure one is not already loaded
if MyReg.LoadKey('TEMP_HIVE', sPathToUserHive) then
begin
//ShowMessage( 'Loaded' );
MyReg.OpenKey('TEMP_HIVE', False);
if MyReg.OpenKey('TEMP_HIVE\Environment', True) then
begin
// --- Make changes *here* ---
//
MyReg.WriteString('KEY_TO_WRITE', 'VALUE_TO_WRITE');
//
//
end;
//Alright, close it up
MyReg.CloseKey;
MyReg.UnLoadKey('TEMP_HIVE');
//let's unload the hive since we are done with it
end
else
begin
WriteLn('Error Loading: ' + sPathToUserHive);
end;
finally
FreeAndNil(MyReg);
end;
end;
WriteLn('Required privilege not held');
end;
finally
FreeAndNil(UserPriv);
end;
end;
I also wrote a VBScript a while ago that accomplishes this task. I used it for modifying some Internet Explorer settings, but you can customize it to your needs. It also demonstrates the general process:
Option Explicit
Dim fso
Dim WshShell
Dim objShell
Dim RegRoot
Dim strRegPathParent01
Dim strRegPathParent02
Set fso = CreateObject("Scripting.FileSystemObject")
Set WshShell = CreateObject("WScript.shell")
'==============================================
' Change variables here
'==============================================
'
'This is where our HKCU is temporarily loaded, and where we need to write to it
RegRoot = "HKLM\TEMPHIVE"
'
strRegPathParent01 = "Software\Microsoft\Windows\CurrentVersion\Internet Settings"
strRegPathParent02 = "Software\Microsoft\Internet Explorer\Main"
'
'======================================================================
Call ChangeRegKeys() 'Sets registry keys per user
Sub ChangeRegKeys
'Option Explicit
On Error Resume Next
Const USERPROFILE = 40
Const APPDATA = 26
Dim iResult
Dim iResult1
Dim iResult2
Dim objShell
Dim strUserProfile
Dim objUserProfile
Dim strAppDataFolder
Dim strAppData
Dim objDocsAndSettings
Dim objUser
Set objShell = CreateObject("Shell.Application")
Dim sCurrentUser
sCurrentUser = WshShell.ExpandEnvironmentStrings("%USERNAME%")
strUserProfile = objShell.Namespace(USERPROFILE).self.path
Set objUserProfile = fso.GetFolder(strUserProfile)
Set objDocsAndSettings = fso.GetFolder(objUserProfile.ParentFolder)
'Update settings for the user running the script
'(0 = default, 1 = disable password cache)
WshShell.RegWrite "HKCU\" & strRegPathParent01 & "\DisablePasswordCaching", "00000001", "REG_DWORD"
WshShell.RegWrite "HKCU\" & strRegPathParent02 & "\FormSuggest PW Ask", "no", "REG_SZ"
strAppDataFolder = objShell.Namespace(APPDATA).self.path
strAppData = fso.GetFolder(strAppDataFolder).Name
' Enumerate subfolders of documents and settings folder
For Each objUser In objDocsAndSettings.SubFolders
' Check if application data folder exists in user subfolder
If fso.FolderExists(objUser.Path & "\" & strAppData) Then
'WScript.Echo "AppData found for user " & objUser.Name
If ((objUser.Name <> "All Users") and _
(objUser.Name <> sCurrentUser) and _
(objUser.Name <> "LocalService") and _
(objUser.Name <> "NetworkService")) then
'Load user's HKCU into temp area under HKLM
iResult1 = WshShell.Run("reg.exe load " & RegRoot & " " & chr(34) & objDocsAndSettings & "\" & objUser.Name & "\NTUSER.DAT" & chr(34), 0, True)
If iResult1 <> 0 Then
WScript.Echo("*** An error occurred while loading HKCU: " & objUser.Name)
Else
WScript.Echo("HKCU loaded: " & objUser.Name)
End If
WshShell.RegWrite RegRoot & "\" & strRegPathParent01 & "\DisablePasswordCaching", "00000001", "REG_DWORD"
WshShell.RegWrite RegRoot & "\" & strRegPathParent02 & "\FormSuggest PW Ask", "no", "REG_SZ"
iResult2 = WshShell.Run("reg.exe unload " & RegRoot,0, True) 'Unload HKCU from HKLM
If iResult2 <> 0 Then
WScript.Echo("*** An error occurred while unloading HKCU: " & objUser.Name & vbcrlf)
Else
WScript.Echo(" unloaded: " & objUser.Name & vbcrlf)
End If
End If
Else
'WScript.Echo "No AppData found for user " & objUser.Name
End If
Next
End Sub
We had the exact same issue the other day.
We discovered that you can just open the HKEY_USERS hive and write the changes to each user's SID.
And, If you want the settings to be present for any new users, you should also apply the settings to the HKEY_USERS/.DEFAULT key.
That is to say, just write your settings to...
HKEY_USERS\S-1-5-XX-XXXXXXXX-XXXXXXXXX-XXXXXXXX-XXXX\Software\...
For each of the SIDs present and:
HKEY_USERS\.DEFAULT\Software\...

VBScript FTP Login with Username and Password

I am trying to update a VBScript (very little experience with this, I do a lot of VB.NET), that reads an FTP directory and moves certain files to a new local directory on a daily basis. I have old code that works on an FTP site that uses anonymous logins, but I now need it to access an FTP site that requires username and password.
Here is my current code -
Sub MoveNSPurolatorFile()
Dim NSPurolatorFTPSite, NSPurolatorMoveFilePath, NSPurolatorFTPFolder, NSPurolatorFTPFileName
Dim folder, files
Dim fso
set fso = CreateObject("Scripting.FileSystemObject")
NSPurolatorFTPSite="\\xxx.xxx.x.xx\"
NSPurolatorMoveFilePath = "F:\TestDirectory"
NSPurolatorFTPFolder = "TestFolder"
NSPurolatorFTPFileName = "MAN0201.CSV"
If InStr(NSPurolatorFTPFileName, "_processed") = 0 and InStr(NSPurolatorFTPFileName, ".CSV") > 0 Then
If fso.FolderExists(NSPurolatorFTPSite & NSPurolatorFTPFolder) Then
If fso.FileExists(NSPurolatorFTPSite & NSPurolatorFTPFolder & NSPurolatorFTPFileName) Then
objfile.writeline "NS Purolator File Found: " & NSPurolatorFTPSite & NSPurolatorFTPFolder & NSPurolatorFTPFileName
fso.copyFile NSPurolatorFTPSite & NSPurolatorFTPFolder & NSPurolatorFTPFileName, NSPurolatorMoveFilePath & "\"
Else
objfile.writeline "File does not exist: " & NSPurolatorFTPSite & NSPurolatorFTPFolder & NSPurolatorFTPFileName
End If
End If
End If
Next
End Sub
It says the folder does not exist, but I know it does and when I run this code against an ftp site that does not require username and password it works fine. I guess my question is - How do I pass in the username and password using VBScript to the ftp site before trying to access folders, etc?
Thanks.
This really is an incredibly bad way to do this. You can't just treat folders on a remote FTP site as local folders.
You really should be using InetCtrls.Inet.1
Here's an example I lifted from somewhere else that does not do what you want, but contains all the parts you need - you need to pick it apart to suit your needs.
'Option Explicit
'const progname="FTP upload script by Richard Finegold"
'const url = "ftp://ftp.myftpsite.com"
'const rdir = "mydir"
'const user = "anonymous"
'const pass = "myname#mymailsite.com"
'This is an example of ftp'ing without calling the external "FTP" command
'It uses InetCtrls.Inet.1 instead
'Included is a "hint" for simple downloading
'Sources:
'http://msdn.microsoft.com/library/partbook/ipwvb5/loggingontoftpserver.htm
'http://msdn.microsoft.com/library/partbook/egvb6/addinginternettransfercontrol.htm
'http://cwashington.netreach.net/ - search on "ftp" - inspiration only!
'Insist on arguments
dim objArgs
Set objArgs = Wscript.Arguments
If 0=objArgs.Count Then
MsgBox "No files selected for operation!", vbOkOnly + vbCritical, progname
WScript.Quit
End If
'Force console mode - csforce.vbs (with some reorganization for efficiency)
dim i
if right(ucase(wscript.FullName),11)="WSCRIPT.EXE" then
dim args, y
For i = 0 to objArgs.Count - 1
args = args + " " + objArgs(i)
Next
Set y = WScript.CreateObject("WScript.Shell")
y.Run "cscript.exe " & wscript.ScriptFullName + " " + args, 1
wscript.quit
end if
'Do actual work
dim fso, ftpo
set fso = WScript.CreateObject("Scripting.FileSystemObject")
set ftpo = WScript.CreateObject("InetCtls.Inet.1") 'Msinet.ocx
ftpo.URL = url
ftpo.UserName = user
ftpo.Password = pass
WScript.Echo "Connecting..."
ftpo.Execute , "CD " & rdir
do
' WScript.Echo "."
WScript.Sleep 100 'This can take a while loop while ftpo.StillExecuting
for i = 0 to objArgs.Count - 1
dim sLFile
sLFile = objArgs(i)
if (fso.FileExists(sLFile)) then
WScript.Echo "Uploading " & sLFile & " as " & FSO.GetFileName(sLFile) & " "
ftpo.Execute , "Put " & sLFile & " " & FSO.GetFileName(sLFile)
'ftpo.Execute , "Get " & sRemoteFile & " C:\" & sLFile
do
'WScript.Echo "."
WScript.Sleep 100 'This can take a while
loop while ftpo.StillExecuting
else
MsgBox Chr(34) & sLFile & Chr(34) & " does not exist!", _
vbOkOnly, progname
end if
next
WScript.Echo "Closing"
ftpo.Execute , "Close"
WScript.Echo "Done!"
Here's a pretty nice way to do it - I'm sure this could be improved upon, but I just got it going.. :-)
Dim fso, folder1, folder2, folder2a
Set fso = CreateObject("Scripting.FileSystemObject")
Set folder2a = fso.GetFolder("C:\temp")
ftpFolderString = "ftp://username:password#ftp.ftpsite.com/folderpath"
targetFoldder = "C:\temp"
fileSearchStr = "searchstring"
Dim SH, txtFolderToOpen, thing
Set SH = CreateObject("Shell.Application")
'SH.Open txtFolderToOpen
Set folder1 = SH.NameSpace(ftpFolderString)
Set folder2 = SH.NameSpace(targetFoldder)
For Each item In folder1.items
If InStr(LCase(item.Name),fileSearchStr) > 0 Then
Debug.WriteLine item.Name
folder2.CopyHere item,4
WScript.Sleep(200)
For Each item2 In folder2a.Files
If item2.Name = item.Name Then
While item2.Size < item.Size
WScript.Sleep(200)
Wend
End If
Next
WScript.Sleep(200)
End If
Next
Set SH = Nothing
Debug.WriteLine "Done"
How is the script being run? Manually, automatically? By a service?
Mapped-letter drives are not always available when running as a service.
Experiment with the script to ensure that it even able to see the F:\ drive, and then see what else is visible.
Is the FTP site accessed by a UNC path (looks like it is)? If it is just a standard FTP address then you can incorporate the username / password in the URL e.g. ftp://user:pass#myftpsite.com. If it is a UNC path that you are trying to access using different credentials then the easiest way would probably be to map a drive, do the work and then unmap the drive. 2 different approaches can be found here

Resources