Ошибка при вызове сценария Power Shell из VBS передачи аргументов - PullRequest
0 голосов
/ 01 февраля 2019

У меня есть очень простой 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.Если я уберу аргумент, то он запустится, но в скрипте 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)

1 Ответ

0 голосов
/ 02 февраля 2019

Ваш VBScript открывает файл со списком файлов XML, а затем пытается передать этот дескриптор сценарию PowerShell.Это не работает.

Есть несколько вещей, которые вы могли бы здесь сделать:

  • Считать листинг XML-файла в VBScript и вызвать скрипт 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 для обработки и вы хотите, чтобы они записывались в разные выходные файлы, вам нужно создать отдельные имена выходных файлов в цикле.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...