powershell - 从传递参数的 vbs 调用 power shell 脚本时出错
问题描述
我有一个非常简单的 VBScript,它执行 PowerShell 脚本并试图传递几个参数。
无论我尝试了什么,它都失败了并且不接受论点:
Dim WshShell
Dim cmdStr
Const ForReading = 1, ForWriting = 2 ,ForAppending = 8
curYear = Year(Date)
curMon = Month(Date)
curDay = Day(Date)
curHr = Hour(Time)
curMin = Minute(Time)
curSec = Second(Time)
datestg = curYear & curMon & curDay & curHr & curMin & curSec
Set WshShell = WScript.CreateObject("WScript.Shell")
Dim inputDir
inputDir = InputBox("Input Directory ( can be full file path ) : ", "Message Box")
inputDirLen = Len(inputDir)
If inputDirLen > 0 Then
lastchar = Mid(inputDir, inputDirLen-1, 1)
If lastchar <> "\" Then
inputDir = inputDir & "\"
End If
End If
outFileMask = InputBox("Output file name mask ( files will be created in previously entered directory ) : ", "Message Box")
newDate = InputBox("Desired Date ( format of the date should be yyyy-mm-ddThh:mm:ss ) : ", "Message Box")
cmdStr = "%comspec% /c dir " & inputDir & "*.xml > dir.lst"
cmdrc = wshShell.Run(cmdStr, , True)
'create file system object
Set fs = CreateObject("Scripting.FileSystemObject")
Set fso = CreateObject("Scripting.FileSystemObject")
dirFileName = "dir.lst"
outFileName = inputDir & outFileMask & "_" & datestg &".xml"
Set infile = fs.OpenTextFile(dirFileName, ForReading)
Set fileOut = fso.CreateTextFile(outFileName, True)
Set objShell = CreateObject("WScript.Shell")
objShell.Run("powershell -NoExit -File .\psscript.ps1 " & infile)
infile.Close
fileOut.Close
WScript.Quit
这甚至失败了objshell.Run
。如果我拿走任何 arg,那么它将运行,但由于参数中的 null 值,它将在 PowerShell 脚本中失败。
这是完整的 PowerShell 脚本:
$inputPath = $args[0]
$newDate = $args[1]
$outputPath = $args[2]
[xml]$xmlDoc = Get-Content $inputPath
foreach ($element in $xmlDoc.element1) {
$element.DateTime = $newDate
}
$xmlDoc.Save($outputPath)
解决方案
您的 VBScript 正在打开带有 XML 文件列表的文件,然后尝试将该句柄传递给 PowerShell 脚本。那是行不通的。
您可以在这里做几件事:
读取 VBScript 中的 XML 文件列表并循环调用 PowerShell 脚本:
Set sh = CreateObject("WScript.Shell") Set fso = CreateObject("Scripting.FileSystemObject") outFileName = inputDir & outFileMask & "_" & datestg &".xml" Set infile = fs.OpenTextFile(dirFileName, ForReading) Do Until infile.AtEndOfStream line = infile.ReadLine sh.Run "powershell -File .\your.ps1 " & line & " " & newDate & " " & outFileName Loop infile.Close
但是,这意味着您要为每次迭代生成一个新进程,这在性能方面很糟糕。
将带有 XML 文件列表的文件传递给 PowerShell 脚本:
Set sh = CreateObject("WScript.Shell") outFileName = inputDir & outFileMask & "_" & newDate &".xml" dirFileName = sh.CurrentDirectory & "\" & dirFileName sh.Run "powershell -File .\your.ps1 " & dirFileName & " " & newDate & " " & outFileName
您希望传递
dirFileName
文件的完整路径,因为不能保证 VBScript 和 PowerShell 代码将具有相同的工作目录。传递列表而不是单个文件也需要更改您的 PowerShell 代码:$inputPath = $args[0] $newDate = $args[1] $outputPath = $args[2] Get-Content $inputPath | ForEach-Object { [xml]$xmlDoc = Get-Content $_.FullName foreach ($element in $xmlDoc.element1) { $element.DateTime = $newDate } $xmlDoc.Save($outputPath) }
传递输入目录并让 PowerShell 列出:
Set sh = CreateObject("WScript.Shell") outFileName = inputDir & outFileMask & "_" & newDate &".xml" sh.Run "powershell -File .\your.ps1 " & inputDir & " " & newDate & " " & outFileName
同样,这也需要更改您的 PowerShell 代码:
$inputPath = $args[0] $newDate = $args[1] $outputPath = $args[2] Get-ChildItem $inputPath -Filter '*.xml' | ForEach-Object { [xml]$xmlDoc = Get-Content $_.FullName foreach ($element in $xmlDoc.element1) { $element.DateTime = $newDate } $xmlDoc.Save($outputPath) }
您还可以在 PowerShell 中完成所有操作并完全放弃 VBScript(这可以说是最干净的方法):
[CmdletBinding()] Param( [Parameter(Mandatory=$true)] [ValidateScript(Test-Path -LiteralPath $_)] [String]$inputPath, [Parameter(Mandatory=$true)] [ValidatePattern('^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$')] [String]$newDate, [Parameter(Mandatory=$true)] [String]$outFileMask ) $datestg = (Get-Date).ToString('yyyyMMddHHmmss') $outFileName = Join-Path $inputPath, "${outFileMask}_${datestg}.xml" Get-ChildItem $inputPath -Filter '*.xml' | ForEach-Object { [xml]$xmlDoc = Get-Content $_.FullName foreach ($element in $xmlDoc.element1) { $element.DateTime = $newDate } $xmlDoc.Save($outFileName) }
但是请注意,使用所有这些方法,PowerShell 将在每次迭代时覆盖输出文件。如果您要处理多个 XML 文件并希望将它们写入不同的输出文件,则需要在循环中创建单独的输出文件名。
推荐阅读
- php - 什么是 mcrypt_get_block 替代方案以及如何使用它
- java - maven shade没有用manifest创建胖罐
- arrays - 由于双 for 循环导致运行时问题
- android - 如何使用 Api 将 Api 文件发送到服务器?带改造2
- c# - 多线程套接字连接挂起 c#。套接字超时/挂起
- python - 具有分类数据的 Pandas 系列直方图
- ssis - 从 SSIS 运行 Winscp 执行进程任务
- clojure - 热修复“警告:任何?已经引用:#'clojure.core/any?在命名空间:leiningen.midje,被替换为:#'leiningen.midje/any?”
- r - 如何在R中提取列表的元素?
- javascript - 从无线电输入更改标签的图像