单击button1时,将执行以下代码,该代码将运行PowerShell脚本以获取当前的SQL Server实例。但是,运行此操作时,结果集(结果变量)的计数为PowerShell输出的0行。当我在本机PowerShell中运行相同的代码时,它会显示包含实例名称的3行。
有人可以告诉我是否遗漏了什么?
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 :(得分:2)
要获得可能的PowerShell错误,我会尝试......像这样:
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);
}
}
}
}
答案 1 :(得分:0)
它不起作用的原因是psInstance.AddParameter
仅向命令添加参数,它不适用于脚本。 You'll need to find another way of getting the $server parameter into the script.试试这两个powershell示例,看看我的意思。第一个将输出所有进程(忽略AddParameter),而第二个只显示svchost进程。
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 :(得分:0)
我设法通过使用Win32_service而不是SQLPS解决了这个问题。
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;