powershell invoke-command exchange mgmt shell from vba with stdout and stderr retrieval and no credential...
The following requirement(s) I have:
As domain admin user logged on to an administrative client machine
I want to perform some changes on an exchange server using calls
from vba(excel 2013) via powershell to an exchange server (2013).
The client machine runs Windows 10 (1809) and powershell v5.1.17763.1
Upon a button press in the vba excel form I want to perform a trivial
task like getting all info for a specific mailbox user, reading
the results back in from stdout/stderr using WSH.Shell, later on more to come.
Executing the command below does what it shall, with the following two drawbacks:
1) the credentials are still asked again for though already passed to the ScriptBlock as $Cred via -ArgumentList
2) the powershell window does not close automatically after processing, it needs
to be closed actively by the user
Finally, the retrieved stdout/stderr gets me what I want (by the way, is there a direct connection possible as to have the powershell objects retrieved into a vba collection?)
WORKS on commandline (a "one-liner"), yet have to provide credentials via popup:
powershell -Command { $Username = 'MYDOMAINAdministrator'; $Password = 'foobar'; $pass = ConvertTo-SecureString -AsPlainText $Password -Force; $Cred = New-Object System.Management.Automation.PSCredential -ArgumentList $Username,$pass; Invoke-Command -ComputerName Exchange -ArgumentList $Cred -ScriptBlock { $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://exchange.somewhere.com/PowerShell/ -Authentication Kerberos -Credential $Cred; Import-PSSession $Session; Get-Mailbox MYUSER; Remove-PSSession $Session } }
WORKS from vba via WSH.Shell Exec, yet have to provide credentials via popup and have to actively close the powershell console window
(and see me avoiding double quotes (") within the powershell script, havent figured out yet how to escape them correctly ("" doesnt work)):
powershell -Command "& { $Username = 'MYDOMAINAdministrator'; $Password = 'foobar'; $pass = ConvertTo-SecureString -AsPlainText $Password -Force; $Cred = New-Object System.Management.Automation.PSCredential -ArgumentList $Username,$pass; Invoke-Command -ComputerName Exchange -ArgumentList $Cred -ScriptBlock { $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://exchange.somewhere.com/PowerShell/ -Authentication Kerberos -Credential $Cred; Import-PSSession $Session; Get-Mailbox MYUSER; Remove-PSSession $Session } }"
So basically it is writing
powershell -Command "& { ... }"
in vba when called via 'wsh shell exec' instead of
powershell -Command { ... }
on the commandline, this seems to be required to retrieve stdin/stdout correctly, would be glad for suggestions why this is the case or if there is an alternative style to write this, too.
Any suggestions how to get rid of the powershell popup asking for the credential
and how to get rid of the powershell window not going away automatically?
Thanks,
Jeff
P.S.:
For your reference, the vba method to do the powershell call (End Function and #if stuff is broken in the code block, you'll figure it out though):
Public Function execPSCommand(ByVal psCmd As String, Optional ByVal label As String = "Debug") As String()
Dim oShell, oExec
Dim retval(2) As String
retval(0) = ""
retval(1) = ""
Set oShell = CreateObject("WScript.Shell")
Set oExec = oShell.Exec(psCmd)
oExec.stdin.Close ' close standard input before reading output
Const WshRunning = 0
Do While oExec.Status = WshRunning
Sleep 100 ' Sleep a tenth of a second
Loop
Dim stdout As String
Dim stderr As String
stdout = oExec.stdout.ReadAll
stderr = oExec.stderr.ReadAll
retval(0) = stdout
retval(1) = stderr
execPSCommand = retval()
End Function
' Sleep (fractions of a second, milliseconds to be precise) for VBA
'#If VBA7 Then
' Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
'#Else
' Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
'#End If
vba powershell exchange-server wsh
add a comment |
The following requirement(s) I have:
As domain admin user logged on to an administrative client machine
I want to perform some changes on an exchange server using calls
from vba(excel 2013) via powershell to an exchange server (2013).
The client machine runs Windows 10 (1809) and powershell v5.1.17763.1
Upon a button press in the vba excel form I want to perform a trivial
task like getting all info for a specific mailbox user, reading
the results back in from stdout/stderr using WSH.Shell, later on more to come.
Executing the command below does what it shall, with the following two drawbacks:
1) the credentials are still asked again for though already passed to the ScriptBlock as $Cred via -ArgumentList
2) the powershell window does not close automatically after processing, it needs
to be closed actively by the user
Finally, the retrieved stdout/stderr gets me what I want (by the way, is there a direct connection possible as to have the powershell objects retrieved into a vba collection?)
WORKS on commandline (a "one-liner"), yet have to provide credentials via popup:
powershell -Command { $Username = 'MYDOMAINAdministrator'; $Password = 'foobar'; $pass = ConvertTo-SecureString -AsPlainText $Password -Force; $Cred = New-Object System.Management.Automation.PSCredential -ArgumentList $Username,$pass; Invoke-Command -ComputerName Exchange -ArgumentList $Cred -ScriptBlock { $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://exchange.somewhere.com/PowerShell/ -Authentication Kerberos -Credential $Cred; Import-PSSession $Session; Get-Mailbox MYUSER; Remove-PSSession $Session } }
WORKS from vba via WSH.Shell Exec, yet have to provide credentials via popup and have to actively close the powershell console window
(and see me avoiding double quotes (") within the powershell script, havent figured out yet how to escape them correctly ("" doesnt work)):
powershell -Command "& { $Username = 'MYDOMAINAdministrator'; $Password = 'foobar'; $pass = ConvertTo-SecureString -AsPlainText $Password -Force; $Cred = New-Object System.Management.Automation.PSCredential -ArgumentList $Username,$pass; Invoke-Command -ComputerName Exchange -ArgumentList $Cred -ScriptBlock { $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://exchange.somewhere.com/PowerShell/ -Authentication Kerberos -Credential $Cred; Import-PSSession $Session; Get-Mailbox MYUSER; Remove-PSSession $Session } }"
So basically it is writing
powershell -Command "& { ... }"
in vba when called via 'wsh shell exec' instead of
powershell -Command { ... }
on the commandline, this seems to be required to retrieve stdin/stdout correctly, would be glad for suggestions why this is the case or if there is an alternative style to write this, too.
Any suggestions how to get rid of the powershell popup asking for the credential
and how to get rid of the powershell window not going away automatically?
Thanks,
Jeff
P.S.:
For your reference, the vba method to do the powershell call (End Function and #if stuff is broken in the code block, you'll figure it out though):
Public Function execPSCommand(ByVal psCmd As String, Optional ByVal label As String = "Debug") As String()
Dim oShell, oExec
Dim retval(2) As String
retval(0) = ""
retval(1) = ""
Set oShell = CreateObject("WScript.Shell")
Set oExec = oShell.Exec(psCmd)
oExec.stdin.Close ' close standard input before reading output
Const WshRunning = 0
Do While oExec.Status = WshRunning
Sleep 100 ' Sleep a tenth of a second
Loop
Dim stdout As String
Dim stderr As String
stdout = oExec.stdout.ReadAll
stderr = oExec.stderr.ReadAll
retval(0) = stdout
retval(1) = stderr
execPSCommand = retval()
End Function
' Sleep (fractions of a second, milliseconds to be precise) for VBA
'#If VBA7 Then
' Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
'#Else
' Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
'#End If
vba powershell exchange-server wsh
add a comment |
The following requirement(s) I have:
As domain admin user logged on to an administrative client machine
I want to perform some changes on an exchange server using calls
from vba(excel 2013) via powershell to an exchange server (2013).
The client machine runs Windows 10 (1809) and powershell v5.1.17763.1
Upon a button press in the vba excel form I want to perform a trivial
task like getting all info for a specific mailbox user, reading
the results back in from stdout/stderr using WSH.Shell, later on more to come.
Executing the command below does what it shall, with the following two drawbacks:
1) the credentials are still asked again for though already passed to the ScriptBlock as $Cred via -ArgumentList
2) the powershell window does not close automatically after processing, it needs
to be closed actively by the user
Finally, the retrieved stdout/stderr gets me what I want (by the way, is there a direct connection possible as to have the powershell objects retrieved into a vba collection?)
WORKS on commandline (a "one-liner"), yet have to provide credentials via popup:
powershell -Command { $Username = 'MYDOMAINAdministrator'; $Password = 'foobar'; $pass = ConvertTo-SecureString -AsPlainText $Password -Force; $Cred = New-Object System.Management.Automation.PSCredential -ArgumentList $Username,$pass; Invoke-Command -ComputerName Exchange -ArgumentList $Cred -ScriptBlock { $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://exchange.somewhere.com/PowerShell/ -Authentication Kerberos -Credential $Cred; Import-PSSession $Session; Get-Mailbox MYUSER; Remove-PSSession $Session } }
WORKS from vba via WSH.Shell Exec, yet have to provide credentials via popup and have to actively close the powershell console window
(and see me avoiding double quotes (") within the powershell script, havent figured out yet how to escape them correctly ("" doesnt work)):
powershell -Command "& { $Username = 'MYDOMAINAdministrator'; $Password = 'foobar'; $pass = ConvertTo-SecureString -AsPlainText $Password -Force; $Cred = New-Object System.Management.Automation.PSCredential -ArgumentList $Username,$pass; Invoke-Command -ComputerName Exchange -ArgumentList $Cred -ScriptBlock { $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://exchange.somewhere.com/PowerShell/ -Authentication Kerberos -Credential $Cred; Import-PSSession $Session; Get-Mailbox MYUSER; Remove-PSSession $Session } }"
So basically it is writing
powershell -Command "& { ... }"
in vba when called via 'wsh shell exec' instead of
powershell -Command { ... }
on the commandline, this seems to be required to retrieve stdin/stdout correctly, would be glad for suggestions why this is the case or if there is an alternative style to write this, too.
Any suggestions how to get rid of the powershell popup asking for the credential
and how to get rid of the powershell window not going away automatically?
Thanks,
Jeff
P.S.:
For your reference, the vba method to do the powershell call (End Function and #if stuff is broken in the code block, you'll figure it out though):
Public Function execPSCommand(ByVal psCmd As String, Optional ByVal label As String = "Debug") As String()
Dim oShell, oExec
Dim retval(2) As String
retval(0) = ""
retval(1) = ""
Set oShell = CreateObject("WScript.Shell")
Set oExec = oShell.Exec(psCmd)
oExec.stdin.Close ' close standard input before reading output
Const WshRunning = 0
Do While oExec.Status = WshRunning
Sleep 100 ' Sleep a tenth of a second
Loop
Dim stdout As String
Dim stderr As String
stdout = oExec.stdout.ReadAll
stderr = oExec.stderr.ReadAll
retval(0) = stdout
retval(1) = stderr
execPSCommand = retval()
End Function
' Sleep (fractions of a second, milliseconds to be precise) for VBA
'#If VBA7 Then
' Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
'#Else
' Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
'#End If
vba powershell exchange-server wsh
The following requirement(s) I have:
As domain admin user logged on to an administrative client machine
I want to perform some changes on an exchange server using calls
from vba(excel 2013) via powershell to an exchange server (2013).
The client machine runs Windows 10 (1809) and powershell v5.1.17763.1
Upon a button press in the vba excel form I want to perform a trivial
task like getting all info for a specific mailbox user, reading
the results back in from stdout/stderr using WSH.Shell, later on more to come.
Executing the command below does what it shall, with the following two drawbacks:
1) the credentials are still asked again for though already passed to the ScriptBlock as $Cred via -ArgumentList
2) the powershell window does not close automatically after processing, it needs
to be closed actively by the user
Finally, the retrieved stdout/stderr gets me what I want (by the way, is there a direct connection possible as to have the powershell objects retrieved into a vba collection?)
WORKS on commandline (a "one-liner"), yet have to provide credentials via popup:
powershell -Command { $Username = 'MYDOMAINAdministrator'; $Password = 'foobar'; $pass = ConvertTo-SecureString -AsPlainText $Password -Force; $Cred = New-Object System.Management.Automation.PSCredential -ArgumentList $Username,$pass; Invoke-Command -ComputerName Exchange -ArgumentList $Cred -ScriptBlock { $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://exchange.somewhere.com/PowerShell/ -Authentication Kerberos -Credential $Cred; Import-PSSession $Session; Get-Mailbox MYUSER; Remove-PSSession $Session } }
WORKS from vba via WSH.Shell Exec, yet have to provide credentials via popup and have to actively close the powershell console window
(and see me avoiding double quotes (") within the powershell script, havent figured out yet how to escape them correctly ("" doesnt work)):
powershell -Command "& { $Username = 'MYDOMAINAdministrator'; $Password = 'foobar'; $pass = ConvertTo-SecureString -AsPlainText $Password -Force; $Cred = New-Object System.Management.Automation.PSCredential -ArgumentList $Username,$pass; Invoke-Command -ComputerName Exchange -ArgumentList $Cred -ScriptBlock { $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://exchange.somewhere.com/PowerShell/ -Authentication Kerberos -Credential $Cred; Import-PSSession $Session; Get-Mailbox MYUSER; Remove-PSSession $Session } }"
So basically it is writing
powershell -Command "& { ... }"
in vba when called via 'wsh shell exec' instead of
powershell -Command { ... }
on the commandline, this seems to be required to retrieve stdin/stdout correctly, would be glad for suggestions why this is the case or if there is an alternative style to write this, too.
Any suggestions how to get rid of the powershell popup asking for the credential
and how to get rid of the powershell window not going away automatically?
Thanks,
Jeff
P.S.:
For your reference, the vba method to do the powershell call (End Function and #if stuff is broken in the code block, you'll figure it out though):
Public Function execPSCommand(ByVal psCmd As String, Optional ByVal label As String = "Debug") As String()
Dim oShell, oExec
Dim retval(2) As String
retval(0) = ""
retval(1) = ""
Set oShell = CreateObject("WScript.Shell")
Set oExec = oShell.Exec(psCmd)
oExec.stdin.Close ' close standard input before reading output
Const WshRunning = 0
Do While oExec.Status = WshRunning
Sleep 100 ' Sleep a tenth of a second
Loop
Dim stdout As String
Dim stderr As String
stdout = oExec.stdout.ReadAll
stderr = oExec.stderr.ReadAll
retval(0) = stdout
retval(1) = stderr
execPSCommand = retval()
End Function
' Sleep (fractions of a second, milliseconds to be precise) for VBA
'#If VBA7 Then
' Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
'#Else
' Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
'#End If
vba powershell exchange-server wsh
vba powershell exchange-server wsh
edited Nov 22 '18 at 17:39
Jeff T. Raccoon
asked Nov 22 '18 at 16:13
Jeff T. RaccoonJeff T. Raccoon
84
84
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
I think you are not passing $cred argument properly to the scriptblock. The scriptblock should start with param($cred) if you want to use that local variable. Why not define $cred inside the scriptblock though? You can also use Using modifier to push local variable to the remote command (like $Using:cred, see more details https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_remote_variables?view=powershell-6 )
Regarding exiting powershell at the end, I guess you can just type "Exit" or "Stop-Process $pid" at the end of your command.
Great stuff, thanks a lot for pointing me into the right direction. Since comments are limited to a really short number of characters, please see my answer below as well ;)
– Jeff T. Raccoon
Nov 26 '18 at 14:06
add a comment |
@Mike: Great stuff, thanks a lot for pointing me into the right direction.
The solution for me was to add "param([PSCredential]$Cred); " as suggested by you.
Of course I could have created $Cred inside the ScriptBlock as well ;)
Furthermore I remembered to have read somewhere that a PSSession should be
closed by a Remove-PSSession command afterwards in order to free up resources.
BUT: this approach clashed with the way I was busy waiting for the wsh shell command to finish (in vba) and then reading stdout/stderr from the process
expecting to close soon - so I removed the busy wait in vba for this particular
case (remote ps session).
It turned out that I did not need to call Remove-PSsession at all, cross-checked
that with a Start-Sleep 60 as the last command (instead of Remove-PSsession)
and executed "Get-PSsession -ComputerName exchange" once in a while on a
real powershell console while execution went on in vba; as soon as the 60 seconds
did pass the session was cleaned up automatically (no more sessions listed).
So the short story is: omit busy waiting when a remote PSSession is done in the ps script (something behind the scenes seems to already have removed that process or anything else not yet clear to me gets in the way in a blocking manner) - why oExec.Status is still left on WshRunning in the 'busy waiting
case' is beyond me, I was expecting it to be either WshFinished or WshFailed,
but that way it caused a blocking powershell window waiting forever.
Anyway, hardcoded vba password is gone as well, read in instead using an inputbox now,
happy powershelling may continue ;)
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53434803%2fpowershell-invoke-command-exchange-mgmt-shell-from-vba-with-stdout-and-stderr-re%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
I think you are not passing $cred argument properly to the scriptblock. The scriptblock should start with param($cred) if you want to use that local variable. Why not define $cred inside the scriptblock though? You can also use Using modifier to push local variable to the remote command (like $Using:cred, see more details https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_remote_variables?view=powershell-6 )
Regarding exiting powershell at the end, I guess you can just type "Exit" or "Stop-Process $pid" at the end of your command.
Great stuff, thanks a lot for pointing me into the right direction. Since comments are limited to a really short number of characters, please see my answer below as well ;)
– Jeff T. Raccoon
Nov 26 '18 at 14:06
add a comment |
I think you are not passing $cred argument properly to the scriptblock. The scriptblock should start with param($cred) if you want to use that local variable. Why not define $cred inside the scriptblock though? You can also use Using modifier to push local variable to the remote command (like $Using:cred, see more details https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_remote_variables?view=powershell-6 )
Regarding exiting powershell at the end, I guess you can just type "Exit" or "Stop-Process $pid" at the end of your command.
Great stuff, thanks a lot for pointing me into the right direction. Since comments are limited to a really short number of characters, please see my answer below as well ;)
– Jeff T. Raccoon
Nov 26 '18 at 14:06
add a comment |
I think you are not passing $cred argument properly to the scriptblock. The scriptblock should start with param($cred) if you want to use that local variable. Why not define $cred inside the scriptblock though? You can also use Using modifier to push local variable to the remote command (like $Using:cred, see more details https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_remote_variables?view=powershell-6 )
Regarding exiting powershell at the end, I guess you can just type "Exit" or "Stop-Process $pid" at the end of your command.
I think you are not passing $cred argument properly to the scriptblock. The scriptblock should start with param($cred) if you want to use that local variable. Why not define $cred inside the scriptblock though? You can also use Using modifier to push local variable to the remote command (like $Using:cred, see more details https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_remote_variables?view=powershell-6 )
Regarding exiting powershell at the end, I guess you can just type "Exit" or "Stop-Process $pid" at the end of your command.
edited Nov 23 '18 at 3:44
answered Nov 23 '18 at 3:38
Mike TwcMike Twc
1,1111312
1,1111312
Great stuff, thanks a lot for pointing me into the right direction. Since comments are limited to a really short number of characters, please see my answer below as well ;)
– Jeff T. Raccoon
Nov 26 '18 at 14:06
add a comment |
Great stuff, thanks a lot for pointing me into the right direction. Since comments are limited to a really short number of characters, please see my answer below as well ;)
– Jeff T. Raccoon
Nov 26 '18 at 14:06
Great stuff, thanks a lot for pointing me into the right direction. Since comments are limited to a really short number of characters, please see my answer below as well ;)
– Jeff T. Raccoon
Nov 26 '18 at 14:06
Great stuff, thanks a lot for pointing me into the right direction. Since comments are limited to a really short number of characters, please see my answer below as well ;)
– Jeff T. Raccoon
Nov 26 '18 at 14:06
add a comment |
@Mike: Great stuff, thanks a lot for pointing me into the right direction.
The solution for me was to add "param([PSCredential]$Cred); " as suggested by you.
Of course I could have created $Cred inside the ScriptBlock as well ;)
Furthermore I remembered to have read somewhere that a PSSession should be
closed by a Remove-PSSession command afterwards in order to free up resources.
BUT: this approach clashed with the way I was busy waiting for the wsh shell command to finish (in vba) and then reading stdout/stderr from the process
expecting to close soon - so I removed the busy wait in vba for this particular
case (remote ps session).
It turned out that I did not need to call Remove-PSsession at all, cross-checked
that with a Start-Sleep 60 as the last command (instead of Remove-PSsession)
and executed "Get-PSsession -ComputerName exchange" once in a while on a
real powershell console while execution went on in vba; as soon as the 60 seconds
did pass the session was cleaned up automatically (no more sessions listed).
So the short story is: omit busy waiting when a remote PSSession is done in the ps script (something behind the scenes seems to already have removed that process or anything else not yet clear to me gets in the way in a blocking manner) - why oExec.Status is still left on WshRunning in the 'busy waiting
case' is beyond me, I was expecting it to be either WshFinished or WshFailed,
but that way it caused a blocking powershell window waiting forever.
Anyway, hardcoded vba password is gone as well, read in instead using an inputbox now,
happy powershelling may continue ;)
add a comment |
@Mike: Great stuff, thanks a lot for pointing me into the right direction.
The solution for me was to add "param([PSCredential]$Cred); " as suggested by you.
Of course I could have created $Cred inside the ScriptBlock as well ;)
Furthermore I remembered to have read somewhere that a PSSession should be
closed by a Remove-PSSession command afterwards in order to free up resources.
BUT: this approach clashed with the way I was busy waiting for the wsh shell command to finish (in vba) and then reading stdout/stderr from the process
expecting to close soon - so I removed the busy wait in vba for this particular
case (remote ps session).
It turned out that I did not need to call Remove-PSsession at all, cross-checked
that with a Start-Sleep 60 as the last command (instead of Remove-PSsession)
and executed "Get-PSsession -ComputerName exchange" once in a while on a
real powershell console while execution went on in vba; as soon as the 60 seconds
did pass the session was cleaned up automatically (no more sessions listed).
So the short story is: omit busy waiting when a remote PSSession is done in the ps script (something behind the scenes seems to already have removed that process or anything else not yet clear to me gets in the way in a blocking manner) - why oExec.Status is still left on WshRunning in the 'busy waiting
case' is beyond me, I was expecting it to be either WshFinished or WshFailed,
but that way it caused a blocking powershell window waiting forever.
Anyway, hardcoded vba password is gone as well, read in instead using an inputbox now,
happy powershelling may continue ;)
add a comment |
@Mike: Great stuff, thanks a lot for pointing me into the right direction.
The solution for me was to add "param([PSCredential]$Cred); " as suggested by you.
Of course I could have created $Cred inside the ScriptBlock as well ;)
Furthermore I remembered to have read somewhere that a PSSession should be
closed by a Remove-PSSession command afterwards in order to free up resources.
BUT: this approach clashed with the way I was busy waiting for the wsh shell command to finish (in vba) and then reading stdout/stderr from the process
expecting to close soon - so I removed the busy wait in vba for this particular
case (remote ps session).
It turned out that I did not need to call Remove-PSsession at all, cross-checked
that with a Start-Sleep 60 as the last command (instead of Remove-PSsession)
and executed "Get-PSsession -ComputerName exchange" once in a while on a
real powershell console while execution went on in vba; as soon as the 60 seconds
did pass the session was cleaned up automatically (no more sessions listed).
So the short story is: omit busy waiting when a remote PSSession is done in the ps script (something behind the scenes seems to already have removed that process or anything else not yet clear to me gets in the way in a blocking manner) - why oExec.Status is still left on WshRunning in the 'busy waiting
case' is beyond me, I was expecting it to be either WshFinished or WshFailed,
but that way it caused a blocking powershell window waiting forever.
Anyway, hardcoded vba password is gone as well, read in instead using an inputbox now,
happy powershelling may continue ;)
@Mike: Great stuff, thanks a lot for pointing me into the right direction.
The solution for me was to add "param([PSCredential]$Cred); " as suggested by you.
Of course I could have created $Cred inside the ScriptBlock as well ;)
Furthermore I remembered to have read somewhere that a PSSession should be
closed by a Remove-PSSession command afterwards in order to free up resources.
BUT: this approach clashed with the way I was busy waiting for the wsh shell command to finish (in vba) and then reading stdout/stderr from the process
expecting to close soon - so I removed the busy wait in vba for this particular
case (remote ps session).
It turned out that I did not need to call Remove-PSsession at all, cross-checked
that with a Start-Sleep 60 as the last command (instead of Remove-PSsession)
and executed "Get-PSsession -ComputerName exchange" once in a while on a
real powershell console while execution went on in vba; as soon as the 60 seconds
did pass the session was cleaned up automatically (no more sessions listed).
So the short story is: omit busy waiting when a remote PSSession is done in the ps script (something behind the scenes seems to already have removed that process or anything else not yet clear to me gets in the way in a blocking manner) - why oExec.Status is still left on WshRunning in the 'busy waiting
case' is beyond me, I was expecting it to be either WshFinished or WshFailed,
but that way it caused a blocking powershell window waiting forever.
Anyway, hardcoded vba password is gone as well, read in instead using an inputbox now,
happy powershelling may continue ;)
edited Nov 27 '18 at 7:10
answered Nov 26 '18 at 14:08
Jeff T. RaccoonJeff T. Raccoon
84
84
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53434803%2fpowershell-invoke-command-exchange-mgmt-shell-from-vba-with-stdout-and-stderr-re%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown