Not:
Aşağıdaki çözüm herhangi bir harici programla çalışır ve çıktıyı her zaman metin olarak yakalar .
To çağırmak başka PowerShell örneği ve onun çıkış yakalamak zengin nesneler olarak (sınırlamalar), alt bölümdeki varyant çözüm görmek veya dikkate Mathias R. Jessen en faydalı bir yanıt kullanır PowerShell SDK .
Hafızadaki işlem çıktısını yakalamak için System.Diagnostics.Process
ve System.Diagnostics.ProcessStartInfo
.NET türlerinin doğrudan kullanımına dayanan bir kavram kanıtı (sorunuzda belirtildiği gibi Start-Process
bir seçenek değildir, çünkü bu cevapta gösterildiği gibi yalnızca dosyalarda çıktı yakalamayı destekler ) :
Not:
Farklı bir kullanıcı olarak çalıştığından, bu yalnızca Windows'ta (.NET Core 3.1'den itibaren), ancak her iki PowerShell sürümünde de desteklenir.
Nedeniyle farklı bir kullanıcı olarak çalıştırmak gerek ve yakalama çıkışına ihtiyacı için, .WindowStyle
komutu çalıştırmak için kullanılamaz gizli (kullanarak çünkü .WindowStyle
gerektirir .UseShellExecute
olmak $true
bu şartlara uyumlu olan); Bütün çıktı ediliyor beri Ancak yakalanan ayarı .CreateNoNewWindow
için $true
etkin bir gizli yürütülmesi ile sonuçlanır.
# Get the target user's name and password.
$cred = Get-Credential
# Create a ProcessStartInfo instance
# with the relevant properties.
$psi = [System.Diagnostics.ProcessStartInfo] @{
# For demo purposes, use a simple `cmd.exe` command that echoes the username.
# See the bottom section for a call to `powershell.exe`.
FileName = 'cmd.exe'
Arguments = '/c echo %USERNAME%'
# Set this to a directory that the target user
# is permitted to access.
WorkingDirectory = 'C:\' #'
# Ask that output be captured in the
# .StandardOutput / .StandardError properties of
# the Process object created later.
UseShellExecute = $false # must be $false
RedirectStandardOutput = $true
RedirectStandardError = $true
# Uncomment this line if you want the process to run effectively hidden.
# CreateNoNewWindow = $true
# Specify the user identity.
# Note: If you specify a UPN in .UserName
# (user@doamin.com), set .Domain to $null
Domain = $env:USERDOMAIN
UserName = $cred.UserName
Password = $cred.Password
}
# Create (launch) the process...
$ps = [System.Diagnostics.Process]::Start($psi)
# Read the captured standard output.
# By reading to the *end*, this implicitly waits for (near) termination
# of the process.
# Do NOT use $ps.WaitForExit() first, as that can result in a deadlock.
$stdout = $ps.StandardOutput.ReadToEnd()
# Uncomment the following lines to report the process' exit code.
# $ps.WaitForExit()
# "Process exit code: $($ps.ExitCode)"
"Running ``cmd /c echo %USERNAME%`` as user $($cred.UserName) yielded:"
$stdout
Yukarıda belirtilenler, sürecin verilen kullanıcı kimliğiyle başarılı bir şekilde yürütüldüğünü gösteren aşağıdaki gibi bir şey verir:
Running `cmd /c echo %USERNAME%` as user jdoe yielded:
jdoe
Yana başka aradığınız PowerShell örneği , sen isteyebilirsiniz yararlanmak PowerShell CLI içine çıktı deserializing verir CLIXML biçiminde çıktı temsil etmek 'ın yeteneği zengin nesneler sınırlı tip sadakat de olsa olarak açıklandığı, bu ilgili cevap .
# Get the target user's name and password.
$cred = Get-Credential
# Create a ProcessStartInfo instance
# with the relevant properties.
$psi = [System.Diagnostics.ProcessStartInfo] @{
# Invoke the PowerShell CLI with a simple sample command
# that calls `Get-Date` to output the current date as a [datetime] instance.
FileName = 'powershell.exe'
# `-of xml` asks that the output be returned as CLIXML,
# a serialization format that allows deserialization into
# rich objects.
Arguments = '-of xml -noprofile -c Get-Date'
# Set this to a directory that the target user
# is permitted to access.
WorkingDirectory = 'C:\' #'
# Ask that output be captured in the
# .StandardOutput / .StandardError properties of
# the Process object created later.
UseShellExecute = $false # must be $false
RedirectStandardOutput = $true
RedirectStandardError = $true
# Uncomment this line if you want the process to run effectively hidden.
# CreateNoNewWindow = $true
# Specify the user identity.
# Note: If you specify a UPN in .UserName
# (user@doamin.com), set .Domain to $null
Domain = $env:USERDOMAIN
UserName = $cred.UserName
Password = $cred.Password
}
# Create (launch) the process...
$ps = [System.Diagnostics.Process]::Start($psi)
# Read the captured standard output, in CLIXML format,
# stripping the `#` comment line at the top (`#< CLIXML`)
# which the deserializer doesn't know how to handle.
$stdoutCliXml = $ps.StandardOutput.ReadToEnd() -replace '^#.*\r?\n'
# Uncomment the following lines to report the process' exit code.
# $ps.WaitForExit()
# "Process exit code: $($ps.ExitCode)"
# Use PowerShell's deserialization API to
# "rehydrate" the objects.
$stdoutObjects = [Management.Automation.PSSerializer]::Deserialize($stdoutCliXml)
"Running ``Get-Date`` as user $($cred.UserName) yielded:"
$stdoutObjects
"`nas data type:"
$stdoutObjects.GetType().FullName
Yukarıdaki çıktı, aşağıdaki gibi bir şey çıkarır ve by [datetime]
( System.DateTime
) çıktısının Get-Date
serisini kaldırılmıştır:
Running `Get-Date` as user jdoe yielded:
Friday, March 27, 2020 6:26:49 PM
as data type:
System.DateTime