2016-12-30 89 views
6

Düğme1 tıklatıldığında, geçerli SQL Server Örneklerini almak için bir PowerShell komut dosyasını çalıştıran aşağıdaki kod çalıştırılır. Ancak, bu çalıştırıldığında, sonuç kümesi (sonuç değişkeni), PowerShell çıkışından 0 satırlık bir sayıya sahiptir. Aynı kodu yerel PowerShell'de çalıştırdığımda, örnek adlarıyla 3 satır görüntüler.Powershell resultset C# yakalanamadı C#

Bir şey özlüyorsam herhangi biri önerilebilir mi?

private void button1_Click(object sender, EventArgs e) 
{ 
    //If the logPath exists, delete the file 
    string logPath = "Output.Log"; 
    if (File.Exists(logPath)) 
    { 
     File.Delete(logPath); 
    } 
    string[] Servers = richTextBox1.Text.Split('\n'); 

    //Pass each server name from the listview to the 'Server' variable 
    foreach (string Server in Servers) 
    { 
     //PowerShell Script 
     string PSScript = @" 
     param([Parameter(Mandatory = $true, ValueFromPipeline = $true)][string] $server) 

     Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned -Force; 
     Import-Module SQLServer; 
     Try 
     { 
      Set-Location SQLServer:\\SQL\\$server -ErrorAction Stop; 
      Get-ChildItem | Select-Object -ExpandProperty Name; 
     } 
     Catch 
     { 
      echo 'No SQL Server Instances'; 
     } 
     "; 

     //Create PowerShell Instance 
     PowerShell psInstance = PowerShell.Create(); 

     //Add PowerShell Script 
     psInstance.AddScript(PSScript); 

     //Pass the Server variable in to the $server parameter within the PS script 
     psInstance.AddParameter("server", Server); 

     //Execute Script 
     Collection<PSObject> results = new Collection<PSObject>(); 
     try 
     { 
      results = psInstance.Invoke(); 
     } 
     catch (Exception ex) 
     { 
      results.Add(new PSObject((Object)ex.Message)); 
     } 

     //Loop through each of the results in the PowerShell window 
     foreach (PSObject result in results) 
     { 
      File.AppendAllText(logPath, result + Environment.NewLine); 
      // listBox1.Items.Add(result); 
     } 
     psInstance.Dispose(); 
    } 
} 
+0

Bu bir Windows Forms Uygulaması mı yoksa başka bir şey mi? Başka bir şey varsa ne? – TravisEz13

+0

Evet, öyle. Şimdi WinForms etiketini ekledim, teşekkürler. –

+2

PowerShell nesnesinde ['HadErrors'] (https://msdn.microsoft.com/en-us/library/system.management.automation.powershell.haderrors (v = vs.85) .aspx) uygunluğunu kontrol edin. Eğer doğruysa, ['Streams'] 'i okumalısınız (https://msdn.microsoft.com/en-us/library/system.management.automation.powershell.streams (v = vs.85) .aspx) ['.Error'] (https://msdn.microsoft.com/en-us/library/system.management.automation.psdatastreams.error (v = vs.85) .aspx) özelliği ve hataları kontrol edin. CmdLet yazılmamış bir hata yazmış olabilir. – TravisEz13

cevap

0

yerine sqlps ait Win32_Service kullanarak bu sorunu yuvarlak başardı.

Param([Parameter(Mandatory = $true, ValueFromPipeline = $true)][string] $server) 

$localInstances = @() 
[array]$captions = GWMI Win32_Service -ComputerName $server | ?{$_.Name -match 'mssql *' -and $_.PathName -match 'sqlservr.exe'} | %{$_.Caption} 

ForEach($caption in $captions) 
{ 
    if ($caption -eq 'MSSQLSERVER') 
    { 
     $localInstances += 'MSSQLSERVER' 
    } 
    else 
    { 
     $temp = $caption | %{$_.split(' ')[-1]} | %{$_.trimStart('(')} | %{$_.trimEnd(')')} 
     $localInstances += ""$server\$temp"" 
    } 
} 
$localInstances; 
2

Olası bir PowerShell hatası almak için sth. Böyle: o çalışmıyor

private void button1_Click(object sender, EventArgs e) 
     { 
      //If the logPath exists, delete the file 
      string logPath = "Output.Log"; 
      if (File.Exists(logPath)) { 
       File.Delete(logPath); 
      } 

      string[] Servers = richTextBox1.Text.Split('\n'); 

      //Pass each server name from the listview to the 'Server' variable 
      foreach (string Server in Servers) { 
       //PowerShell Script 
       string PSScript = @" 
      param([Parameter(Mandatory = $true, ValueFromPipeline = $true)][string] $server) 

      Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned -Force; 
      Import-Module SQLServer; 
      Try 
      { 
       Set-Location SQLServer:\\SQL\\$server -ErrorAction Stop; 
       Get-ChildItem | Select-Object -ExpandProperty Name; 
      } 
      Catch 
      { 
       echo 'No SQL Server Instances'; 
      } 
      "; 
       using (PowerShell psInstance = PowerShell.Create()) {        
        psInstance.AddScript(PSScript); 
        psInstance.AddParameter("server", Server); 
        Collection<PSObject> results = psInstance.Invoke(); 
        if (psInstance.Streams.Error.Count > 0) { 
         foreach (var errorRecord in psInstance.Streams.Error) { 
          MessageBox.Show(errorRecord.ToString()); 
         } 
        }    
        foreach (PSObject result in results) { 
         File.AppendAllText(logPath, result + Environment.NewLine); 
         // listBox1.Items.Add(result); 
        }    
       } 

      } 
     } 
+0

Kod daha yakından bakınca, kod tüm hataları yakalamak ve sonra bir hata varsa, bir dizgi çıktılamak için "yazma-çıktı" için bir takma ad olan echo özelliğini kullanın. Bu yüzden çoğu hata aslında bir sonuca neden olur, bir hata değildir. Ayrıca, bu yorum yazılmadan önce, 'HadErrors' özelliğinin yanlış olduğu yönünde bir yorum var. – TravisEz13

0

nedeni psInstance.AddParameter sadece komutlara parametreler ekler yani, bir komut dosyası ile çalışmaz. You'll need to find another way of getting the $server parameter into the script. Ne demek istediğimi görmek için bu iki powershell örneğini deneyin. İlk, tüm süreçleri (AddParameter'ı göz ardı eder) verirken, ikincisi sadece svchost süreçlerini gösterir.

1)

$ps = [system.management.automation.powershell]::create() 
$ps.AddScript("get-process") 
$ps.AddParameter("name","svchost") 
$ps.invoke() 

2)

$ps = [system.management.automation.powershell]::create() 
$ps.AddCommand("get-process") 
$ps.AddParameter("name","svchost") 
$ps.invoke() 
+2

Powershell kodunu "Try {echo $ server; } 'beklenen değişkeni döndürür, bu yüzden sorun değil. Parametreyi sorun olmadan iletir –