Reputation: 188
For reasons that should not impact the current question I need to run a script, with the definition and parameters outside the command, inside a different PowerShell instance, without using PSSessions, background jobs or files (I have working examples for PSSession, background jobs and .ps1 files and I'm aware they can replace what I'm trying to do, but I need a working example with powershell.exe -Command
as well).
I looked at the help for powershell.exe
, and it should support what I am trying to do, but I can't get it working with all that I need (script definition and parameters outside the command).
As a working example I have:
$abc = powershell.exe -WindowStyle Hidden -NonInteractive -Command {Invoke-Command -ScriptBlock {
param($a1,$a2)
$a1*6
$a2*5} -Argumentlist @(8,'abc')}
I need to be able to at least move the -ArgumentList
outside the command, like:
$abc = powershell.exe -WindowStyle Hidden -NonInteractive -Command {Invoke-Command -ScriptBlock {
param($a1,$a2)
$a1*6
$a2*5} -Argumentlist @($args[0],$args[1])} -args @(8,'abc')
and even better have:
$script={
param($a1,$a2)
$a1*6
$a2*5}
$args=@(8,'abc')
$abc = powershell.exe -WindowStyle Hidden -NonInteractive -Command $script -args $args
I already looked at the following similar questions, but couldn't find what I needed:
Upvotes: 16
Views: 46185
Reputation: 437258
user4003407 has provided the crucial pointer:
Remove -WindowStyle Hidden
from your call.
By using it, you're hiding the current console window, i.e. you're making the caller's window disappear, which is clearly not the intent.
If you're concerned about unwanted output from the CLI call:
$abc =
, due to capturing success output, you're effectively hiding it.2>$null
to silence (non-terminating) errors.*>$null
would silence all streams (including the success output stream, which precludes capturing).Apart from that, the last call in your question uses the correct syntax, whose overall form is, using powershell.exe
, the Windows PowerShell CLI (the same applies analogously to pwsh
, the PowerShell (Core) CLI):
# Note: Works only from INSIDE PowerShell
powershell.exe -Command { ... } -args arg1, ...
Note:
-Command
may be preceded by other parameters, such as -NoProfile
- see the linked help topics for details.
-args
must be a ,
-separated list of positional arguments - named arguments (e.g., -foo bar
) are not supported.
param(...)
block, as in your attempt, or you can simply use the automatic $args
variable to access the parameters by index ($args[0]
for the first, ...).Unlike with string-based CLI calls - which are the only option when calling from outside PowerShell - script block-based calls offer rich type support, within the type-fidelity limitations of PowerShell's XML-based serialization infrastructure - see this answer - and support for all output streams.
Upvotes: 1
Reputation: 3151
This answer isn't 100% relevant to the original poster, because they are trying to run PowerShell from within PowerShell. I am trying to run it PowerShell from either a command prompt, or specifically WMI. A little background: the reason I'm trying to do this is because PowerShell remoting is not enabled on my target machine and I want to enable it. I can't use winrm
because it requires user input. So, this works:
$x=Get-WmiObject -ComputerName "<computer name>" -Namespace "root\cimv2" -Class "Win32_Process" -List
$x.Create('C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -Command "& C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -Command {Enable-PSRemoting}"',$null,$null)
Results:
__GENUS : 2
__CLASS : __PARAMETERS
__SUPERCLASS :
__DYNASTY : __PARAMETERS
__RELPATH :
__PROPERTY_COUNT : 2
__DERIVATION : {}
__SERVER :
__NAMESPACE :
__PATH :
ProcessId : 12508
ReturnValue : 0
PSComputerName :
I should probably post this in a different question, but this one came up on a google search for "how to pass scriptblock to powershell.exe", so I thought it would be useful here.
Upvotes: 0
Reputation: 1583
Not sure if this helps I added a few things to your original script and changed $args to $z and it seemed to work.
$script={
param($a1 =1 ,$a2 = 2)
$a1*6
$a2*5
test-connection -Count 2 www.google.com
Write-Output $a1
Write-Output $a2
}
$z=@(8,'abc')
$abc = powershell.exe -WindowStyle Hidden -NonInteractive -Command $script -args $z
$abc
48
abcabcabcabcabc
PSComputerName : ok
IPV4Address :1.1.1.4
IPV6Address :
__GENUS : 2
__CLASS : Win32_PingStatus
__SUPERCLASS :
__DYNASTY : Win32_PingStatus
__RELPATH : Win32_PingStatus.Address="www.google.com",BufferSize=32,NoFragmentation=FALSE,RecordRoute=0,ResolveAddressNames=FALSE,SourceRou
te="",SourceRouteType=0,Timeout=4000,TimestampRoute=0,TimeToLive=80,TypeofService=0
__PROPERTY_COUNT : 24
__DERIVATION : {}
__SERVER : ok
__NAMESPACE : root\cimv2
__PATH : \\ok\root\cimv2:Win32_PingStatus.Address="www.google.com",BufferSize=32,NoFragmentation=FALSE,RecordRoute=0,ResolveAddressName
s=FALSE,SourceRoute="",SourceRouteType=0,Timeout=4000,TimestampRoute=0,TimeToLive=80,TypeofService=0
Address : www.google.com
BufferSize : 32
NoFragmentation : False
PrimaryAddressResolutionStatus : 0
ProtocolAddress :1.1.1.4
ProtocolAddressResolved :
RecordRoute : 0
ReplyInconsistency : False
ReplySize : 32
ResolveAddressNames : False
ResponseTime : 19
ResponseTimeToLive : 252
RouteRecord :
RouteRecordResolved :
SourceRoute :
SourceRouteType : 0
StatusCode : 0
Timeout : 4000
TimeStampRecord :
TimeStampRecordAddress :
TimeStampRecordAddressResolved :
TimestampRoute : 0
TimeToLive : 80
TypeofService : 0
PSComputerName : ok
IPV4Address :1.1.1.4
IPV6Address :
__GENUS : 2
__CLASS : Win32_PingStatus
__SUPERCLASS :
__DYNASTY : Win32_PingStatus
__RELPATH : Win32_PingStatus.Address="www.google.com",BufferSize=32,NoFragmentation=FALSE,RecordRoute=0,ResolveAddressNames=FALSE,SourceRou
te="",SourceRouteType=0,Timeout=4000,TimestampRoute=0,TimeToLive=80,TypeofService=0
__PROPERTY_COUNT : 24
__DERIVATION : {}
__SERVER : ok
__NAMESPACE : root\cimv2
__PATH : \\ok\root\cimv2:Win32_PingStatus.Address="www.google.com",BufferSize=32,NoFragmentation=FALSE,RecordRoute=0,ResolveAddressName
s=FALSE,SourceRoute="",SourceRouteType=0,Timeout=4000,TimestampRoute=0,TimeToLive=80,TypeofService=0
Address : www.google.com
BufferSize : 32
NoFragmentation : False
PrimaryAddressResolutionStatus : 0
ProtocolAddress :1.1.1.4
ProtocolAddressResolved :
RecordRoute : 0
ReplyInconsistency : False
ReplySize : 32
ResolveAddressNames : False
ResponseTime : 21
ResponseTimeToLive : 252
RouteRecord :
RouteRecordResolved :
SourceRoute :
SourceRouteType : 0
StatusCode : 0
Timeout : 4000
TimeStampRecord :
TimeStampRecordAddress :
TimeStampRecordAddressResolved :
TimestampRoute : 0
TimeToLive : 80
TypeofService : 0
8
abc
Upvotes: 3