我正在使用 Excel VBA 运行一个简单的 Powershell 脚本,该脚本在 Powershell 本身中运行时,会返回给定目录中某些文件的一两个文件名。
我可以从 VBA 运行此脚本,但返回值始终是一些随机整数。如何让脚本返回通过 Powershell 脚本返回的文件名?
调用脚本的VBA:
Dim weekly As String
weekly = Shell("Powershell ""<location of powershell script.ps1>"" ")
脚本:
Get-ChildItem "<directory to search in>" | Where-Object {$_.Name -match "<regex to find file name>"}
如果我遗漏任何细节,请询问。
我知道这已经太晚了,但我想让其他正在寻找此方法的人能够做到这一点。 让您的 powershell 脚本写入输出文件:
Get-ChildItem "Directory to Search" | Select-String -Pattern "what to seach for" | out-file "C:\output.txt"
从那里您可以将其逐行写入变量:
Sub test()
Dim txtfile, text, textline As String
txtfile = "C:\output.txt"
Open txtfile For Input As #1
Do Until EOF(1)
Line Input #1, textline
text = text & textline
Loop
Close #1
MsgBox text
End Sub
您可以将文本插入到单元格中,或者如果愿意,您可以将每一行写入数组,并根据需要单独选择每一行。
您可以使用 WScript 访问 PowerShell 脚本的 StdOut 输出。使用以下代码:
Set wShell = CreateObject("WScript.Shell")
Set wShellOutput = wShell.Exec("powershell 'C:\Path\To\file.ps1'")
text_output = wShellOutput.StdOut.ReadAll ()
我建议在 .Exec() 调用中使用单引号而不是双引号,因为 Windows 处理双引号很痛苦。
看起来 VBA 只是看到 powershell.exe 退出时使用的退出代码。 试试这个:
Get-ChildItem "<directory to search in>" | Where-Object {$_.Name -match "<regex to find file name>"} 2>&1
我相信这会将您的 Powershell 输出重定向到 VBA 应该能够获取的标准输出。
尝试使用下面的 Powershell 函数来运行 powershell 命令并返回输出。该代码将命令的结果输出到临时文件,等待命令完成,然后返回输出。
该函数使用sub WaitFile等待输出文件完成,轮询时使用Windows sleep功能等待100ms。
Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Function Powershell(Command As String) As String
'Runs powershell command and returns output
Dim FilePath As String
Dim OutFile As String
Dim fso As Object
'Generate output file name
FilePath = ThisWorkbook.Path
Set fso = CreateObject("Scripting.FileSystemObject")
OutFile = FilePath & "\" & fso.GetTempName()
Set fso = Nothing
'Delete output file if it exists
DelFile OutFile
'Add output file to command
Command = SPrintF("%s | out-file -FilePath %s -Encoding ASCII", Command, OutFile)
'Run command
Shell SPrintF("Powershell ""%s""", Command), vbMinimizedNoFocus
'Wait for temp file to appear
WaitFile OutFile
'Gather results from temp file
Powershell = GetFile(OutFile)
'Delete output file if it exists
DelFile OutFile
End Function
Sub WaitFile(FileName As String, Optional TimeOutSecs As Long = 60)
'Returns entire contents of file
Dim fhan As Long
Dim s As String
Dim StartTime As Date
On Error Resume Next
'Initialise start time
StartTime = Now
'Wait for file to appear (or time out)
Do While FileLen(FileName) = 0
Sleep 100
DoEvents
If DateDiff("s", StartTime, Now) > TimeOutSecs Then Exit Do
Loop
End Sub