ROM
asked on
Get output from Powershell commands in VB or VBA.
Hey All,
How can I get the output from the following commands please.
562 Set wsh = New WshShell
572 strCom = Chr(34) & _
"C:\Apps\PSCodeRunner\RunC ode.cmd" & _
Chr(34)
582 lngErrorCode = wsh.Run(strCom, _
WindowStyle:=0, _
WaitOnReturn:=True)
I have a powershell being executed in that file as follows:
C:\windows\sysnative\Windo wsPowerShe ll\v1.0\po wershell.e xe -NoExit -Command "cd \; [console]::Title='RC PS Processor'; [IntPtr]::Size; c:\apps\PSCodeRunner\PSScr ipt.ps1; Exit"
I have tried piping in clip such as | clip but the only kind of output I get is:
WARNING: The names of some imported commands from the module 'tmp_hsh4edta.1jr' include unapproved verbs that might
make them less discoverable. To find the commands with unapproved verbs, run the Import-Module command again with the
Verbose parameter. For a list of approved verbs, type Get-Verb.
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Script 1.0 tmp_hsh4edta.1jr {Add-AvailabilityAddressSp ace, Add-DistributionGroupMembe r...
And what I want is the actual output you get from the PS ISE etc... or PS generally.
Please advise
Many thanks
R
How can I get the output from the following commands please.
562 Set wsh = New WshShell
572 strCom = Chr(34) & _
"C:\Apps\PSCodeRunner\RunC
Chr(34)
582 lngErrorCode = wsh.Run(strCom, _
WindowStyle:=0, _
WaitOnReturn:=True)
I have a powershell being executed in that file as follows:
C:\windows\sysnative\Windo
I have tried piping in clip such as | clip but the only kind of output I get is:
WARNING: The names of some imported commands from the module 'tmp_hsh4edta.1jr' include unapproved verbs that might
make them less discoverable. To find the commands with unapproved verbs, run the Import-Module command again with the
Verbose parameter. For a list of approved verbs, type Get-Verb.
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Script 1.0 tmp_hsh4edta.1jr {Add-AvailabilityAddressSp
And what I want is the actual output you get from the PS ISE etc... or PS generally.
Please advise
Many thanks
R
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks everyone
I originally was doing all of this within VBScript in VBA in MSAccess as this is what the application is written in.
However, after lots of testing it was found that VBA in MSAccess will NOT run the 64bit of PowerShell.
So the workaround is getting a file I call from VBA to kick off a new PowerShell command outside of VBA and MSAccess therefore allowing 64bit PowerShell and therefore all my 365 commands work as they were not before.
Hence the setup I need to achieve.
I would prefer to run the other way, however, after a lot of work and testing and help from EE as well.. this is what worked so I could run commands against 365..
So that is where I need to get the results from please.
Thanks
R
I originally was doing all of this within VBScript in VBA in MSAccess as this is what the application is written in.
However, after lots of testing it was found that VBA in MSAccess will NOT run the 64bit of PowerShell.
So the workaround is getting a file I call from VBA to kick off a new PowerShell command outside of VBA and MSAccess therefore allowing 64bit PowerShell and therefore all my 365 commands work as they were not before.
Hence the setup I need to achieve.
I would prefer to run the other way, however, after a lot of work and testing and help from EE as well.. this is what worked so I could run commands against 365..
So that is where I need to get the results from please.
Thanks
R
ASKER
HI Michael.. however not output I can see please.
Thanks
R
Thanks
R
ASKER
Hi Michael,
But I want to take the output into VBA and do something with it in the App
R
But I want to take the output into VBA and do something with it in the App
R
I went back and re-read the entire thread. You didn't state that anywhere, just that you wanted to "get the output".
Regardless, it's a simple matter of re-directing the PowerShell output to a temporary file and then opening that file in the VBS. Do you know how to do that?
Regardless, it's a simple matter of re-directing the PowerShell output to a temporary file and then opening that file in the VBS. Do you know how to do that?
ASKER
Hi Michael.. I do state the output twice in the Original Question.
Anyway....
I am assuming > c:\filename within the command somewhere? However I tried CLIP and it gave me the above.
Is there something further to do? As I want the results like Powershell NOT the output I had earlier.
Thanks in advance
R
R
Anyway....
I am assuming > c:\filename within the command somewhere? However I tried CLIP and it gave me the above.
Is there something further to do? As I want the results like Powershell NOT the output I had earlier.
Thanks in advance
R
R
ASKER
Could you supply an example please
Thanks
R
Thanks
R
Sorry, I had to do some actual work this morning. :-)
Here it is, all nice and neat and pretty.
Here it is, all nice and neat and pretty.
Option Explicit
Const ForReading = 1
Const ForWriting = 2
Const ForAppending = 8
Const TristateUseDefault = -2
Const TristateTrue = -1
Const TristateFalse = 0
Sub e (str)
WScript.Echo str
End Sub
Function ErrorReport (str)
If Err.Number Then
ErrorReport = True
e "Error 0x" & CStr (Hex (Err.Number)) & " occurred " & str
If Err.Description <> "" Then
e "Error description: " & Err.Description & "."
End If
Err.Clear
Else
ErrorReport = False
End If
End Function
Function TmpFolder
Dim temp: temp = oShell.ExpandEnvironmentStrings("%Temp%")
e "TmpFolder = " & temp
TmpFolder = temp
End Function
Function TmpFileName
Dim objRan
Set objRan = CreateObject("System.Random")
Dim ran: ran = objRan.Next_2( 1, 10000 )
Set objRan = Nothing
Dim temp: temp = TmpFolder
Dim file: file = temp & "\" & ran
'' file is the name of the file where your PowerShell output is redirected
e "TmpFileName = " & file
TmpFileName = file
End Function
Function DummyPowerShellScript
Dim file, oFile
file = TmpFolder & "\" & "dummy.ps1"
e "DummyPowerShellScript = " & file
Set oFile = oFS.OpenTextFile(file, ForWriting, True, TristateFalse)
If ErrorReport ("while creating " & file) Then
WScript.Quit 1
End If
oFile.WriteLine "write-host -fore green powershell output"
oFile.WriteLine "dir"
oFile.Close
If ErrorReport ("while closing " & file) Then
WScript.Quit 1
End If
Set oFile = Nothing
DummyPowerShellScript = file
End Function
Function DummyBatch (psFile, temp)
Dim file, oFile
file = TmpFolder & "\" & "dummy.bat"
Set oFile = oFS.OpenTextFile(file, ForWriting, True, TristateFalse)
If ErrorReport ("while creating " & file) Then
WScript.Quit 1
End If
oFile.WriteLine "powershell.exe -NoExit -Command " & Chr(34) & _
"& { " & _
"[Console]::Title='RC PS Processor'; " & _
"[IntPtr]::Size; " & _
psFile & " | Out-File -LiteralPath '" & temp & "' -Encoding ascii; " & _
"sleep 2; " & _
"exit; " & _
"}" & _
Chr(34)
oFile.Close
If ErrorReport ("while closing " & file) Then
WScript.Quit 1
End If
Set oFile = Nothing
DummyBatch = file
End Function
Sub ReadTmpFile(file)
Dim objFile, strLine
WScript.Echo "About to open = " & file
''On Error Resume Next
Set objFile = oFS.OpenTextFile(file, ForReading)
If ErrorReport ("while opening " & file) Then
WScript.Quit 1
End If
Do While Not objFile.AtEndOfStream
strLine = objFile.ReadLine()
'' Do something with strLine
e "strLine = " & strLine
Loop
objFile.Close
If ErrorReport ("while closing " & file) Then
WScript.Quit 1
End If
Set objFile = Nothing
End Sub
Sub Wait (sec)
Dim temp
temp = Timer
Do While Timer-temp<sec
Loop
End Sub
''
'' Main
''
''On Error Resume Next
Dim oShell, oFS
Dim temp, file, psFile
Set oShell = WScript.CreateObject("WScript.Shell")
If ErrorReport ("while creating WScript.Shell") Then
WScript.Quit 1
End If
Set oFS = CreateObject("Scripting.FileSystemObject")
If ErrorReport ("while creating Scripting.FileSystemObject") Then
WScript.Quit 1
End If
psFile = DummyPowerShellScript
temp = TmpFileName
file = DummyBatch(psFile, temp)
'' use /k if you want the cmd.exe session to hang around
''oShell.Run "cmd.exe /k " & file
oShell.Run "cmd.exe /c " & file
Wait 1
ReadTmpFile(temp)
Set oFS = Nothing
Set oShell = Nothing
ASKER
@Coralon
Could you explain a little more about the error message please and approved verbs.
So I understand please.
Thanks
R
Could you explain a little more about the error message please and approved verbs.
So I understand please.
Thanks
R
Microsoft only "approves" specific verbs. If a verb is unapproved, then anytime you use that cmdlet, it will throw warning messages that the verb is unapproved. It doesn't actually *stop* anything.. but it's ugly, and for production level scripts, it's not something you want hanging around. (The old PowerCLI module had some cmdlets with unapproved verbs).
Your error message said that one of the exported commands from the module tmp_hsh4edta.1jr had an unapproved verb. You can use Get-Verb to see the list of approved verbs. For your module, I would run a get-command -module tmp_hsh4edta.1jr to see which command has the unapproved verb.
The other piece to this is if your command is a single word.. like TestSomething, it will *not* throw that unapproved warning message. My guess is that it is because it is not in the verb-noun format as expected (although personally, I'd think that it should throw a warning about the cmdlet construction being incorrect, but that's just me :-)
Coralon
Your error message said that one of the exported commands from the module tmp_hsh4edta.1jr had an unapproved verb. You can use Get-Verb to see the list of approved verbs. For your module, I would run a get-command -module tmp_hsh4edta.1jr to see which command has the unapproved verb.
The other piece to this is if your command is a single word.. like TestSomething, it will *not* throw that unapproved warning message. My guess is that it is because it is not in the verb-noun format as expected (although personally, I'd think that it should throw a warning about the cmdlet construction being incorrect, but that's just me :-)
Coralon
The warning message the OP got is from importing the Exchange module.
As @Coralon wrote, it's just a warning. And the OP can suppress it. Not likely they are going to update Exchange. :-)
As @Coralon wrote, it's just a warning. And the OP can suppress it. Not likely they are going to update Exchange. :-)
ASKER
LOL... not updating correct :).
I think this is because I had a clobber command.
Removed now.
WIll continue to test in the development.
WIll feedback, thanks
R
I think this is because I had a clobber command.
Removed now.
WIll continue to test in the development.
WIll feedback, thanks
R
Good to know that the Exchange modules have a "bad" cmdlet name in them. Glad the MS doesn't even follow their own standards.. lol..
Over 600 Exchange cmdlets were written before PowerShell 1.0 was released. The standards didn't exist - at that time they were "guidelines" and even PowerShell itself didn't follow all the guidelines. (This was when Exchange 2007 was in beta and PowerShell at the time was called "Monad".)
ASKER
Thanks Michael.
This is now in production ;)
R
This is now in production ;)
R
The error you are getting is pretty straightforward. When you import a command (by module, dot sourcing, etc.) if your functions have a single word name, they won't generate an error, but if powershell sees the - in the name, then your verb has to be from the approved verb list, or you get that error.
Anyway.. back to the original question. Look at the MSDN documentation for ProcessStartInfo. You can configure that in your powershell to capture the StdOut, StdErr, etc. https://docs.microsoft.com
You'll configure the RedirectStandardOutput and RedirectStandardError, set the UseShellExecute to $false in your configuration and go from there.
Here's an example from one of my old scripts (semi-sanitized)
Open in new window
from there, you can use your $Process.StandardOutput and $Process.StandardError to do whatever you want with them.
Coralon