首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法检索通过FailoverCluster执行的WSFC FailoverCluster Powershell模块的结果

无法检索通过FailoverCluster执行的WSFC FailoverCluster Powershell模块的结果
EN

Stack Overflow用户
提问于 2021-10-05 17:20:47
回答 1查看 145关注 0票数 1

由于没有访问WindowsServerFailoverCluster特性的集成方法或API,所以我尝试启动一些PowerShell cmdlet来确定PowerShell的状态并将其返回给C# (健康检查)

这是一个冒烟测试,包含PowerShell的控制台输出,其中包含我的对象,但不幸的是,它是一个扁平的字符串。

备选案文1:

代码语言:javascript
复制
System.Diagnostics.ProcessStartInfo processInfo = new System.Diagnostics.ProcessStartInfo();
processInfo.FileName = @"powershell.exe";
processInfo.Arguments = @"& {Get-ClusterResource -Name '"+ _wsfcResourceName +"'}";
processInfo.Verb = "runas";
processInfo.RedirectStandardError = true;
processInfo.RedirectStandardOutput = true;
processInfo.UseShellExecute = false;
processInfo.CreateNoWindow = true;

System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo = processInfo;
process.Start();

var stdout = process.StandardOutput.ReadToEnd();
var stderror = process.StandardError.ReadToEnd();

一旦我尝试了这样的方法:

代码语言:javascript
复制
System.Management.Automation.Runspaces.InitialSessionState initialSessionState = System.Management.Automation.Runspaces.InitialSessionState.CreateDefault();
initialSessionState.ImportPSModule(new[] { "FailoverClusters"});
initialSessionState.ExecutionPolicy = Microsoft.PowerShell.ExecutionPolicy.Unrestricted;
using System.Management.Automation.Runspaces.Runspace runspace = System.Management.Automation.Runspaces.RunspaceFactory.CreateRunspace(initialSessionState);
runspace.Open();
using (PowerShell PowerShellInst = PowerShell.Create(runspace))
{
    PowerShellInst.AddCommand($@"Get-ClusterResource");
    PowerShellInst.AddParameter("Name", _wsfcResourceName);
    
    //Same result using these
    //PowerShellInst.AddScript($@"Get-ClusterResource -Name '{_wsfcResourceName}'");
    //PowerShellInst.AddScript($@"Import-Module FailoverClusters; Get-ClusterResource -Name '{_wsfcResourceName}'");

    Collection<PSObject> PSOutput = PowerShellInst.Invoke();
    var rsrcResults = PSOutput.ToList();
... etc

..。应用程序从PowerShell抛出一个异常

代码语言:javascript
复制
The 'Get-ClusterResource' command was found in the module 'FailoverClusters', but the module could not be loaded. Fore more information, run 'Import-Module FailoverClusters'.

当选项1起作用时(这是从IIS Web应用程序运行的),这让我感到困惑。

我尝试过的事情:

  1. 只传递"Import-Module FailoverClusters -Force -Verbose"以查看它是否出错。It doesn't.
  2. Specifying initialSessionState.ImportPSModule(new[] { "FailoverClusters"}); in Runspaces.InitialSessionState
  3. Specifying 32位在我的类库中处理这个方法
  4. .没有不同的写作方法。--

有人能给我点建议吗?

更新到@Cpt.Whale的答复:

代码更改为:

代码语言:javascript
复制
PowerShellInst.Commands.AddCommand("Import-Module").AddArgument(@"FailoverClusters");
                        PowerShellInst.Commands.AddParameter("SkipEditionCheck");
                        PowerShellInst.Commands.AddParameter("Force");
                        PowerShellInst.Commands.AddParameter("Verbose");

我现在打电话给:Collection<PSObject> PSOutput = PowerShellInst.Invoke();

我第一次看到一个例外:

代码语言:javascript
复制
System.Management.Automation.CmdletInvocationException: Could not load type 'System.Diagnostics.Eventing.EventDescriptor' from assembly 'System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.
---> System.TypeLoadException: Could not load type 'System.Diagnostics.Eventing.EventDescriptor' from assembly 'System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.
 at Microsoft.FailoverClusters.UI.Common.TraceWriterEtw.TraceCmdletEnter(String cmdletName, String invocation, String parameters, UInt32 sequence, String source, String tag)
 at Microsoft.FailoverClusters.UI.Common.TraceCmdlet.Starting()
 at Microsoft.FailoverClusters.UI.Common.TraceSampleBase.Start() 
at Microsoft.FailoverClusters.UI.Common.ClusterLog.StartTraceCmdlet(TraceSource source, String cmdletName, String invocation, String parameters) at Microsoft.FailoverClusters.PowerShell.FCCmdlet.ProcessRecord()
 at Microsoft.FailoverClusters.PowerShell.ClusterPipeCmdlet.ProcessRecord() at System.Management.Automation.CommandProcessor.ProcessRecord() --- End of inner exception stack trace --- at System.Management.Automation.Runspaces.PipelineBase.Invoke(IEnumerable input) at System.Management.Automation.PowerShell.Worker.ConstructPipelineAndDoWork(Runspace rs, Boolean performSyncInvoke)
 at System.Management.Automation.PowerShell.Worker.CreateRunspaceIfNeededAndDoWork(Runspace rsToUse, Boolean isSync) at System.Management.Automation.PowerShell.CoreInvokeHelper[TInput,TOutput](PSDataCollection`1 input, PSDataCollection`1 output, PSInvocationSettings settings)
 at System.Management.Automation.PowerShell.CoreInvoke[TInput,TOutput](PSDataCollection`1 input, PSDataCollection`1 output, PSInvocationSettings settings) at System.Management.Automation.PowerShell.Invoke(IEnumerable input, PSInvocationSettings settings)

还不知道这意味着什么..。

编辑#2

代码语言:javascript
复制
"Import-Module errors out when it attempts to load the module 
with an error message stating that Import-Module was not able to load the 
.NET type System.Diagnostics.Eventing.EventDescriptor. Since the EventDescriptor 
type is not available in .NET Core, you cannot use the ServerManager module natively. 
The only alternatives are for the Server Manager team to update their code, 
or for you to run the  cmdlet in Windows PowerShell (either explicitly or via the compatibility mechanism)" 

我相信这解释了为什么“备选方案1”有效。这让我回到了我开始的地方。有没有用process.StandardOutput.ReadToEnd()制作某种对象?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-06 02:01:17

我想知道如何完成我想要的事情的唯一方法是依赖这样一个事实:我的PSOBject只有少量的对象,并且我可以确定我可以安全地假设它们中没有空间。

然后,我调用StartProcess()以我的cmdlet作为参数启动powershell,但将其转换为"Format-List -HideTableHeaders",然后使用空格作为分隔符进行解析。

代码语言:javascript
复制
public async Task<string> GetClusterResource()
{
  try
   {
    System.Diagnostics.ProcessStartInfo processInfo = new System.Diagnostics.ProcessStartInfo();
    processInfo.FileName = @"powershell.exe";

    processInfo.Arguments = @"& {Get-ClusterResource -Name '" + _wsfcResourceName + "' | Select Name, State, OwnerGroup | ft -HideTableHeaders}";
                    
    processInfo.RedirectStandardError = true;
    processInfo.RedirectStandardOutput = true;
    processInfo.UseShellExecute = false;
    processInfo.CreateNoWindow = true;


    System.Diagnostics.Process process = new System.Diagnostics.Process();
    process.StartInfo = processInfo;
    process.Start();

    var results = await process.StandardOutput.ReadToEndAsync();
    var errors = await process.StandardError.ReadToEndAsync();

    return results;
   }
   catch (Exception ex)
   {
     throw;
   }
}
代码语言:javascript
复制
var CoreClusterResults = await GetClusterResource();

CoreClusterResults = CleanStringOfNewlineStrings(CoreClusterResults); //this removes any occurences of /r/n, /r or /n

var ParamsSplit = CoreClusterResults.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries);

if (ParamsSplit.Any())
{
   var clusterParamName = ParamsSplit[0];
   var clusterParamValue = ParamsSplit[1];

     ...
}

感谢@Cpt给了这头牛

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69454782

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档