2017-12-27 1896 views
1

當手動運行vs編程時,我得到了來自同一命令的兩個不同輸出,我不明白爲什麼。PowerShell輸出在手動和程序化執行之間有所不同

問題::命令powershell -Command "Get-Module -ListAvailable"

當在命令提示符下手動運行,我得到這個輸出::

U:\>powershell -Command "Get-Module -ListAvailable" 

Directory: C:\Program Files\WindowsPowerShell\Modules 

ModuleType Version Name        ExportedCommands 
---------- ------- ----        ---------------- 
Binary  1.0.0.1 PackageManagement     {Find-Package, Get-Package, Get-PackageProvider, Get-PackageSource...} 
Script  1.0.0.1 PowerShellGet      {Install-Module, Find-Module, Save-Module, Update-Module...} 
Binary  6.5.1.6... VMware.DeployAutomation    {Add-DeployRule, Add-ProxyServer, Add-ScriptBundle, Copy-DeployRule...} 
Binary  6.5.1.6... VMware.ImageBuilder     {Add-EsxSoftwareDepot, Add-EsxSoftwarePackage, Compare-EsxImageProfile, Export-EsxImageProfile...} 
Manifest 6.5.4.7... VMware.PowerCLI 
Binary  6.5.4.6... VMware.VimAutomation.Cis.Core  {Connect-CisServer, Disconnect-CisServer, Get-CisService} 
Binary  6.5.1.5... VMware.VimAutomation.Cloud   {Add-CIDatastore, Connect-CIServer, Disconnect-CIServer, Get-Catalog...} 
Manifest 6.5.4.6... VMware.VimAutomation.Common 
Binary  6.5.2.6... VMware.VimAutomation.Core   {Add-PassthroughDevice, Add-VirtualSwitchPhysicalNetworkAdapter, Add-VMHost, Add-VMHostNtpServer...} 
Binary  6.5.4.7... VMware.VimAutomation.HA    Get-DrmInfo 
Binary  7.1.0.5... VMware.VimAutomation.HorizonView {Connect-HVServer, Disconnect-HVServer} 
Binary  6.5.1.5... VMware.VimAutomation.License  Get-LicenseDataManager 
Binary  2.0.0.6... VMware.VimAutomation.Nsxt   {Connect-NsxtServer, Disconnect-NsxtServer, Get-NsxtService} 
Binary  6.5.1.5... VMware.VimAutomation.PCloud   {Connect-PIServer, Disconnect-PIServer, Get-PIComputeInstance, Get-PIDatacenter} 
Manifest 1.0.0.5... VMware.VimAutomation.Sdk   {Get-PSVersion, Get-InstallPath} 
Binary  6.5.1.5... VMware.VimAutomation.Srm   {Connect-SrmServer, Disconnect-SrmServer} 
Binary  6.5.4.7... VMware.VimAutomation.Storage  {Add-KeyManagementServer, Copy-VDisk, Export-SpbmStoragePolicy, Get-KeyManagementServer...} 
Script  1.1  VMware.VimAutomation.StorageUtility Update-VmfsDatastore 
Binary  6.5.1.5... VMware.VimAutomation.Vds   {Add-VDSwitchPhysicalNetworkAdapter, Add-VDSwitchVMHost, Export-VDPortGroup, Export-VDSwitch...} 
Binary  6.5.4.7... VMware.VimAutomation.Vmc   {Connect-Vmc, Disconnect-Vmc, Get-VmcService, Connect-VmcServer...} 
Binary  6.5.1.5... VMware.VimAutomation.vROps   {Connect-OMServer, Disconnect-OMServer, Get-OMAlert, Get-OMAlertDefinition...} 
Binary  6.5.1.5... VMware.VumAutomation    {Add-EntityBaseline, Copy-Patch, Get-Baseline, Get-Compliance...} 

Directory: C:\Windows\system32\WindowsPowerShell\v1.0\Modules 

ModuleType Version Name        ExportedCommands 
---------- ------- ----        ---------------- 
Manifest 1.0.0.0 AppLocker       {Set-AppLockerPolicy, Get-AppLockerPolicy, Test-AppLockerPolicy, Get-AppLockerFileInformation...} 
Manifest 1.0.0.0 BitsTransfer      {Add-BitsFile, Remove-BitsTransfer, Complete-BitsTransfer, Get-BitsTransfer...} 
Manifest 1.0.0.0 CimCmdlets       {Get-CimAssociatedInstance, Get-CimClass, Get-CimInstance, Get-CimSession...} 
Script  1.0.0.0 ISE         {New-IseSnippet, Import-IseSnippet, Get-IseSnippet} 
Manifest 1.0.0.0 Microsoft.PowerShell.Archive  {Compress-Archive, Expand-Archive} 
Manifest 3.0.0.0 Microsoft.PowerShell.Diagnostics {Get-WinEvent, Get-Counter, Import-Counter, Export-Counter...} 
Manifest 3.0.0.0 Microsoft.PowerShell.Host   {Start-Transcript, Stop-Transcript} 
Manifest 3.1.0.0 Microsoft.PowerShell.Management  {Add-Content, Clear-Content, Clear-ItemProperty, Join-Path...} 
Script  1.0  Microsoft.PowerShell.ODataUtils  Export-ODataEndpointProxy 
Manifest 3.0.0.0 Microsoft.PowerShell.Security  {Get-Acl, Set-Acl, Get-PfxCertificate, Get-Credential...} 
Manifest 3.1.0.0 Microsoft.PowerShell.Utility  {Format-List, Format-Custom, Format-Table, Format-Wide...} 
Manifest 3.0.0.0 Microsoft.WSMan.Management   {Disable-WSManCredSSP, Enable-WSManCredSSP, Get-WSManCredSSP, Set-WSManQuickConfig...} 
Manifest 1.0.0.0 NetworkSwitchManager    {Disable-NetworkSwitchEthernetPort, Enable-NetworkSwitchEthernetPort, Get-NetworkSwitchEthernetPort, Remove-NetworkSwitchEthernetPortIPAddress...} 
Manifest 1.1  PSDesiredStateConfiguration   {Set-DscLocalConfigurationManager, Start-DscConfiguration, Test-DscConfiguration, Publish-DscConfiguration...} 
Script  1.0.0.0 PSDiagnostics      {Disable-PSTrace, Disable-PSWSManCombinedTrace, Disable-WSManTrace, Enable-PSTrace...} 
Binary  1.1.0.0 PSScheduledJob      {New-JobTrigger, Add-JobTrigger, Remove-JobTrigger, Get-JobTrigger...} 
Manifest 2.0.0.0 PSWorkflow       {New-PSWorkflowExecutionOption, New-PSWorkflowSession, nwsn} 
Manifest 1.0.0.0 PSWorkflowUtility     Invoke-AsWorkflow 
Manifest 1.0.0.0 TroubleshootingPack     {Get-TroubleshootingPack, Invoke-TroubleshootingPack} 

Directory: C:\opscode\chefdk\modules 

ModuleType Version Name        ExportedCommands 
---------- ------- ----        ---------------- 
Script  0.0  chef        {chef-apply, chef-client, chef-service-manager, chef-shell...} 

當編程方式運行(通過Java),我得到這樣的輸出::

ModuleType Name      ExportedCommands               
---------- ----      ----------------               
Binary  PackageManagement   {Find-Package, Get-Package, Get-PackageProvider, Get-PackageSource...}  
Script  PowerShellGet    {Install-Module, Find-Module, Save-Module, Update-Module...} 
Manifest BitsTransfer    {Add-BitsFile, Remove-BitsTransfer, Complete-BitsTransfer, Get-BitsTrans... 
Manifest CimCmdlets    {Get-CimAssociatedInstance, Get-CimClass, Get-CimInstance, Get-CimSessio... 
Script  ISE      {New-IseSnippet, Import-IseSnippet, Get-IseSnippet}       
Manifest Microsoft.PowerShell.A... {Compress-Archive, Expand-Archive}           
Manifest Microsoft.PowerShell.D... {Get-WinEvent, Get-Counter, Import-Counter, Export-Counter...}    
Manifest Microsoft.PowerShell.Host {Start-Transcript, Stop-Transcript}           
Manifest Microsoft.PowerShell.M... {Add-Content, Clear-Content, Clear-ItemProperty, Join-Path...}    
Script  Microsoft.PowerShell.O... Export-ODataEndpointProxy             
Manifest Microsoft.PowerShell.S... {Get-Acl, Set-Acl, Get-PfxCertificate, Get-Credential...}     
Manifest Microsoft.PowerShell.U... {Format-List, Format-Custom, Format-Table, Format-Wide...}     
Manifest Microsoft.WSMan.Manage... {Disable-WSManCredSSP, Enable-WSManCredSSP, Get-WSManCredSSP, Set-WSManQ... 
Manifest PSDesiredStateConfigur... {Set-DscLocalConfigurationManager, Start-DscConfiguration, Test-DscConfi... 
Manifest PSDiagnostics    {Start-Trace, Stop-Trace, Enable-WSManTrace, Disable-WSManTrace...}   
Binary  PSScheduledJob   {New-JobTrigger, Add-JobTrigger, Remove-JobTrigger, Get-JobTrigger...}  
Manifest TroubleshootingPack  {Get-TroubleshootingPack, Invoke-TroubleshootingPack}      
Script  chef      {chef-apply, chef-client, chef-service-manager, chef-shell...}    

編程運行i的輸出s缺少「版本」列,並且只是可用模塊的一個子集。

我想也許不知何故,我調用了兩個不同的PowerShell可執行文件,所以我手動和編程運行powershell -Command "$PSVersionTable"

powershell -Command "$PSVersionTable"手動運行::

Name       Value 
----       ----- 
PSVersion      5.0.10586.117 
PSCompatibleVersions   {1.0, 2.0, 3.0, 4.0...} 
BuildVersion     10.0.10586.117 
CLRVersion      4.0.30319.18444 
WSManStackVersion    3.0 
PSRemotingProtocolVersion  2.3 
SerializationVersion   1.1.0.1 

powershell -Command "$PSVersionTable"的綱領性運行::

Name       Value                                         
----       -----                                         
PSVersion      5.0.10586.117                                       
PSCompatibleVersions   {1.0, 2.0, 3.0, 4.0...}                                     
BuildVersion     10.0.10586.117                                       
CLRVersion      4.0.30319.18444                                       
WSManStackVersion    3.0                                          
PSRemotingProtocolVersion  2.3                                          
SerializationVersion   1.1.0.1 

所以我覺得我運行的輸出輸出相同的PowerShell可執行文件。

任何人有什麼想法,爲什麼我運行相同的命令時,我得到2完全不同的輸出?

UPDATE :: 在@EBGreen的要求下,我包含了用於以編程方式運行命令的實際Java代碼。

public class Example { 

    private void myMethod(String command) throws IOException { 
     Process process = Runtime.getRuntime().exec(command); 
     BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream())); 

     String output = ""; 
     String line; 
     while((line = bufferedReader.readLine()) != null){ 
      output += (line + "\n"); 
     } 

     System.out.println((output.isEmpty() ? "No output was received!!!" : output)); 


     BufferedReader errorBufferedReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); 
     String errorOutput = ""; 
     while((line = errorBufferedReader.readLine()) != null){ 
      errorOutput += (line + "\n"); 
     } 

     System.out.println((errorOutput.isEmpty() ? "Nothing in the error output stream." : errorOutput)); 
    } 


    public static void main(String[] args) throws IOException { 
     new Example().myMethod("powershell -Command \"Get-Module -ListAvailable\""); 
    } 

} 
+0

您以編程方式運行時使用的實際代碼是什麼。命令是否在相同的用戶環境中運行?是一個64位和另一個32位? – EBGreen

+0

@EBGreen我會在一秒內發佈一個包含代碼的問題更新。 – Chiefwarpaint

+0

@EBGreen代碼現已包含在帖子中。程序化執行是通過IntelliJ中的32位JDK完成的。手動執行通過cmd提示符('C:\ Windows \ system32 \ cmd.exe')完成。主機操作系統是64位Win 7. – Chiefwarpaint

回答

0

我99.9%肯定這是我問題的真正原因。

當我手動運行命令來檢查可用模塊列表時,我使用的是Powershell的64位實例。

我的Java程序運行在32位上下文中(是針對32位JDK構建的)。當我的程序調用cmd提示符時,它得到一個32位cmd提示符。當cmd提示符調用Powershell時,它得到一個32位Powershell。 PowerShell的32位和64位版本具有獨特的安裝路徑,用於存儲模塊。

所以,當我手動安裝模塊時,我總是使用64位Powershell。我從來沒有手動打開32位Powershell並安裝任何模塊。這就是爲什麼Get-Module -ListAvailable的編程輸出非常小,與我手動運行相同命令時看到的相比較。

感謝@BaconBits爲我提供了幫助我識別發生了什麼的線索。該技巧是執行[Environment]::Is64BitProcess來驗證我的Powershell實際運行的操作系統架構上下文。

1

我的猜測是,你只是沒有得到從Java編程調用時PowerShell的格式化輸出,或不同的版本有一些不同的原因默認格式配置。

首先,一些背景:

你在命令行中運行PowerShell中得到的輸出是通過在格式文件的格式決定。這些都存儲在$PSHome\*.format.ps1xmlGet-Module返回System.Management.Automation.PSModuleInfo類型的對象。如果您運行Select-String -Pattern 'PSModuleInfo' -Path "$PSHome\*.format.ps1xml",則可以找到默認格式的指定位置。 Format-Table將會有Table,這是您通常得到的默認值。 Format-Wide也有WideList也有Format-List。您可以在Get-Help about_Format.ps1xml上了解有關控制檯輸出格式的更多信息。

由於爲PSModuleInfo默認的輸出是使用表格式,你應該能夠通過調用使Java比賽的PowerShell:

new Example().myMethod("powershell -Command \"Get-Module -ListAvailable | Format-Table\""); 

或者可能:

new Example().myMethod("powershell -Command \"Get-Module -ListAvailable | Format-Table | Out-String\""); 

,或者甚至只是:

new Example().myMethod("powershell -Command \"Get-Module -ListAvailable | Out-String\""); 

至於什麼Java做的不同或爲什麼它是n格式類似,恐怕我不知道。

您也可以隨時做這樣的事情:

new Example().myMethod("powershell -Command \"Get-Module -ListAvailable | Out-String\""); 

你也可以有成功與Get-Module -ListAvailable | ConvertTo-Json -Compress -Depth 1Get-Module -ListAvailable | ConvertTo-Xml -NoTypeInformation -As String -Depth 1或者,如果你想你的序列相似的輸出。請記住,默認深度爲ConvertTo-Json爲2,默認深度爲ConvertTo-Xml爲1,而深度爲3以上的任何內容都將爲,真的很慢

+0

Thx一噸的幫助和建議,我相信他們會派上用場。 但是,我現在確定我的真正問題是因爲以下原因: 當我手動運行'powershell -Command「Get-Module -ListAvailable」'時,我通過64位命令運行它提示。然後調用64位PowerShell。 當我以編程方式運行相同的命令時,Java使用的是32位命令提示符。這反過來又調用了32位的PowerShell。 32位和64位具有不同的模塊安裝路徑,所以這就是我得到差異輸出值的原因。 – Chiefwarpaint

相關問題