Visst finns det det. Det här slängde jag ihop nu. Det är hyffsat testat. Det behöver lite mer felhantering och loggning dock. But that is left as an excercise to the reader.
Option Explicit
' Copyright (c) 2009 Olle Lundberg <geek(_at_)nerd(_dot_)sh>
'
' Permission is hereby granted, free of charge, to any person obtaining a copy
' of this software and associated documentation files (the "Software"), to deal
' in the Software without restriction, including without limitation the rights
' to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
' copies of the Software, and to permit persons to whom the Software is
' furnished to do so, subject to the following conditions:
'
' The above copyright notice and this permission notice shall be included in
' all copies or substantial portions of the Software.
'
' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
' IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
' FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
' AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
' LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
' OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
' THE SOFTWARE.
Function ConvertToUncPath(ByVal Path)
Dim Matches,Folder,RegExp : Set RegExp = New RegExp
RegExp.IgnoreCase = True
RegExp.Pattern = "^([a-z]){1}:\\+(.*)"
Set Matches = RegExp.Execute(Path & "\")
RegExp.Pattern = "\\+"
RegExp.Global = True
If Matches.Count > 0 Then
ConvertToUncPath = Array( Matches(0).SubMatches(0) & "$", RegExp.Replace( Matches(0).SubMatches(1), "\" ) )
End If
End Function
Function ParseDomain(Domain)
Dim Matches,RegExp : Set RegExp = New RegExp
RegExp.Pattern = "^DC=([^,]+)"
RegExp.IgnoreCase = True
Set Matches = RegExp.Execute(Domain)
If Matches.Count > 0 Then
ParseDomain = Matches(0).SubMatches(0)
End If
End Function
Function IsOnline(Computer)
IsOnline = False
Dim Ping,Status : Set Ping = GetObject("winmgmts:{impersonationLevel=impersonate}")._
ExecQuery("select Replysize from Win32_PingStatus where address = '" & Computer & "'")
For Each Status in Ping
If Not IsNull(Status.ReplySize) Then
IsOnline = True
End If
Next
End Function
Function GetFreeDrive()
GetFreeDrive = False
Dim TestDrive,I
TestDrive = &H41
Dim FSO : Set FSO = CreateObject("Scripting.FileSystemObject")
For I = 0 to 25
If FSO.DriveExists(Chr(TestDrive)) Then
TestDrive = TestDrive + &H1
Else
GetFreeDrive = Chr(TestDrive) & ":"
Exit For
End If
Next
End Function
Sub EnumerateAndCopy(HostInfo)
Dim ADConn,ADCommand,ADRS,Drive,WSHNetWork, FSO, First
First = True
Set ADConn = CreateObject("ADODB.Connection")
ADConn.Provider = "ADsDSOObject"
ADConn.Open
Set ADCommand = CreateObject("ADODB.Command")
ADCommand.ActiveConnection = ADConn
ADCommand.properties("Page Size")=100
ADCommand.CommandText = "<LDAP://" & HostInfo.Item("RootDSE") & ">;(objectCategory=computer);Name;subTree"
Set ADRS = ADCommand.Execute
Drive = GetFreeDrive()
Set WSHNetWork = CreateObject("Wscript.Network")
Set FSO = CreateObject("Scripting.FileSystemObject")
Do While Not ADRS.EOF
If IsOnline ( ADRS("Name") ) Then
WScript.Echo ADRS("Name") & " is online. Mounting: it on " & Drive
If HostInfo.Exists("User") Then
WSHNetWork.MapNetWorkDrive Drive , "\\" & ADRS("Name") & "\" & HostInfo.Item("To")(0) , False , HostInfo("Domain") & "\" & HostInfo.Item("User") , HostInfo.Item("Password")
Else
WSHNetWork.MapNetWorkDrive Drive , "\\" & ADRS("Name") & "\" & HostInfo.Item("To")(0)
End if
FSO.CopyFile HostInfo.Item("From"), Drive & "\" & HostInfo.Item("To")(1) ,True
WSHNetWork.RemoveNetworkDrive Drive, True
Else
WScript.Echo ADRS("Name") & " is offline."
End If
ADRS.MoveNext
Loop
End Sub
Sub PrintUsage(ErrorMessage)
WScript.Echo "---------------------------------------------------"
WScript.Echo "Author: Olle Lundberg <geek(_at_)nerd(_dot_)sh>"
WScript.Echo "Licensed under a MIT license"
WScript.Echo "---------------------------------------------------"
WScript.Echo ""
WScript.Echo "Usage: cscript.exe " & WScript.ScriptName & " /f:<path> /t:<path> [/u:<user> [/p[:<pass>]] [/d:<domain>]]"
WScript.Echo ""
WScript.Echo " /f:<path> The absolut path to the file you want to copy."
Wscript.Echo " This argument may include environamnet variables"
WScript.Echo " (e.g %WINDIR%)"
WScript.Echo ""
WScript.Echo " /t:<path> The absolut path to the folder you want to copy"
WScript.Echo " the file to"
WScript.Echo ""
WScript.Echo " Optional Arguments: (Parenthesis denotes default value)"
WScript.Echo ""
WScript.Echo " /u:<user> A user that have access to the machines (Current user)"
WScript.Echo ""
WScript.Echo " /p:<pass> Password of the user that has access to"
WScript.Echo " the machines. If you only specify /p"
WScript.Echo " without a value you get to type the password."
Wscript.Echo ""
WScript.Echo " /d:<domain> The domain of the user with access (Default domain in AD)"
If Len(ErrorMessage) > 1 Then
WScript.Echo ""
WScript.Echo "---------------------------------------------------"
WScript.Echo ErrorMessage
WScript.Echo "---------------------------------------------------"
End If
End Sub
Sub ParseArguments()
Dim Arguments: Set Arguments = WScript.Arguments.Named
If InStr(Ucase(WScript.FullName), "CSCRIPT") = 0 Then
CreateObject("WScript.Shell").Run "%comspec% /K cscript.exe //nologo " & Chr(34) & WScript.ScriptFullName & Chr(34)
Wscript.Quit 1
End If
If Not Arguments.Exists("f") _
Or Not Arguments.Exists("t") Then
Call PrintUsage("Missing /f or /t argument")
Wscript.Quit 1
End If
Dim HostInfo : Set HostInfo = CreateObject ("Scripting.Dictionary")
If Arguments.Exists("u") Then
HostInfo.Add "User" , Arguments.Item("u")
End If
HostInfo.Add "RootDSE" , GetObject("LDAP://RootDSE").Get("DefaultNamingContext")
If Not Arguments.Exists("d") Then
HostInfo.Add "Domain" , ParseDomain(HostInfo.Item("RootDSE"))
Else
HostInfo.Add "Domain" , Arguments.Item("d")
End If
If Arguments.Exists("p") Then
If Len(Arguments.Item("p")) = 0 Then
Dim Prompt : Prompt = "Please enter password for " & HostInfo.Item("Domain") & "\" & HostInfo.Item("User") & ":"
WScript.StdOut.Write Prompt
HostInfo.Add "Password" , CreateObject("ScriptPW.Password").GetPassword()
WScript.StdOut.Write String( Len( Prompt ), Chr( 8 ) ) _
& Space( Len( Prompt ) ) _
& String( Len( Prompt ), Chr( 8 ) )
Else
HostInfo.Add "Password" , Arguments.Item("p")
End If
End If
HostInfo.Add "From" , CreateObject("WScript.Shell").ExpandEnvironmentStrings( Arguments.Item("f") )
HostInfo.Add "To" , ConvertToUncPath( Arguments.Item("t") )
Call EnumerateAndCopy(HostInfo)
End Sub
ParseArguments()