I want to execute a PowerShell Command from VBA using WScript.Shell
Here is the string that gets sent to WScript.Shell:
Powershell -ExecutionPolicy Bypass -Command $FilesInPathway = get-childitem -path "C:\Users\Me\Desktop\NewFolder" -recurse -attributes !directory; foreach ($file in $FilesInPathway){$tempName = $file.name; $tempName = $tempName.replace(".TXT",".txt"); Rename-Item $file.fullname $tempName}
And here is the PowerShell Command I want to execute. Note this command does successfully execute in PowerShell.
$FilesInPathway = get-childitem -path "C:\Users\Me\Desktop\NewFolder" -recurse -attributes !directory; foreach ($file in $FilesInPathway){$tempName = $file.name; $tempName = $tempName.replace(".TXT",".txt"); Rename-Item $file.fullname $tempName}
Do not get information that there is an issue executing PowerShell Command, but the Command does not execute and files are not renamed. Msgbox returns no information. Blank form. Want to avoid switching to a PowerShell script or writing this using DIR and NAME.
strCommand = "Powershell -ExecutionPolicy Bypass -Command $FilesInPathway = get-childitem -path " & """" & dataPacket.filePath & """" & " -recurse -Attributes !Directory; foreach ($file in $FilesInPathway){$tempName = $file.name; $tempName = $tempName.replace(" & """" & dataPacket.stringOld & """" & "," & """" & dataPacket.stringNew & """" & "); Rename-Item $file.fullname $tempName}"
Set WshShell = CreateObject("WScript.Shell")
Set WshShellExec = WshShell.Exec(strCommand)
strOutput = WshShellExec.StdOut.ReadAll
MsgBox strOutput
UPDATE I
New Command does traverse the directory tree and returns correct number of files in that tree. It must be the foreach function I am passing that is not executing. But when I run the debug.print version of string directly in Powershell, it executes OK - all files are renamed.
strCommand = "Powershell $FilesInPathway = get-childitem -path " & """" & dataPacket.filePath & """" & " -recurse -attributes !directory; $FilesInPathway.count"
Set WshShell = CreateObject("WScript.Shell")
Set WshShellExec = WshShell.Exec(strCommand)
Do While WshShellExec.Status = 0
Application.Wait (Now() + TimeValue("0:00:01"))
Loop
strOutput = WshShellExec.StdOut.ReadAll
MsgBox strOutput
The string that is passed to WshShell:
Powershell $FilesInPathway = get-childitem -path "C:\Users\Me\Desktop\NewFolder" -recurse -attributes !directory; $FilesInPathway.count
The string that is passed to PowerShell:
$FilesInPathway = get-childitem -path "C:\Users\Me\Desktop\NewFolder" -recurse -attributes !directory; $FilesInPathway.count
Note I have tried to use the StdIn.Write method to isolate Commands but am getting error.
WshShellExec.StdIn.Write "$FilesInPathway.count"
UPDATE II
Running Shell() with a type or enum declared may generate malicious macro warning and kill excel application? Have not isolated code that causes this.
The following will enter infinite loop if -noexit included with Command Do While WshShellExec.Status = 0 Application.Wait (Now() + TimeValue("0:00:01")) Loop
ANSWER
Of course this would be a syntax problem. Need to enclose parameters of Replace method with ' '. If filepath contains a whitespace, it too needs enclosure with ' '. If entered directly into PowerShell, enclosure with " " works fine. So the Command is:
strCommand = "Powershell $FilesInPathway = get-childitem -path " & "'" & dataPacket.filePath & "'" & " -recurse -attributes !directory; foreach ($file in $FilesInPathway){$tempName = $file.name; $tempName = $tempName.replace('" & dataPacket.stringOld & "','" & dataPacket.stringNew & "'); Rename-Item $file.fullname $tempName}"
This seems to explain why: https://stackoverflow.com/a/45762288/9721351