我能够使用一个简单的c#函数,但是当我介绍一些更复杂的东西时,如下面的内容,我会遇到语法错误,并且没有很多关于如何执行此操作的示例.
我已根据此处收到的建议对代码进行了更新,但此代码仍然无法正常运行
cls $dagDistribution = $null; $distribution = @' using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Management.Automation; using System.Management.Automation.Runspaces; using System.Security; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Threading; using System.Collections.Concurrent; using System.Diagnostics; using System.Security.Principal; namespace MultiThreading { public class dagDistribution { public Listget(string dag) { DateTime start = DateTime.Now; var respOnse= new ConcurrentBag >(); var exceptiOns= new ConcurrentQueue (); string dagName = "hqdag1"; string[] serversUnsorted = getDagMembers(dagName); var servers = from s in serversUnsorted orderby s select s; try { Parallel.ForEach(servers, server => { response.Add(runPowerShellScript(server)); }); } catch (AggregateException ae) { foreach (var aex in ae.InnerExceptions) { exceptions.Enqueue(aex); } } List returnValues = new List (); foreach (var item in response) { string returnValue = parseServerResults(item); returnValues.Add(returnValue); } returnValues.Sort(); return returnValues; } private Collection runPowerShellScript(object server) { Collection psobjs = new Collection (); string result = ""; string serverName = server.ToString(); WSManConnectionInfo wmc = new WSManConnectionInfo(new Uri("http://xxx/powershell")); wmc.AuthenticatiOnMechanism= AuthenticationMechanism.Kerberos; wmc.ShellUri = "http://schemas.microsoft.com/powershell/Microsoft.Exchange"; using (Runspace runspace = RunspaceFactory.CreateRunspace(wmc)) { PowerShell powershell = PowerShell.Create(); if (runspace.RunspaceStateInfo.State == RunspaceState.Opened) { // do nothing } else { runspace.Open(); powershell.Runspace = runspace; } try { PSCommand command = new PSCommand(); command.AddScript("get-mailboxdatabase -Server " + server + " -Status"); powershell.Commands = command; psobjs = powershell.Invoke(); if (powershell.HadErrors == true) { result = "Failed - " + powershell.Streams.Error[0].ToString(); result = result.Replace("\"", "*"); } } catch (Exception ex) { string fail = ex.Message; } } object serverNameO = server; PSObject serverNameObj = new PSObject(serverNameO); psobjs.Insert(0, serverNameObj); return psobjs; } private string[] getDagMembers(string dagName) { Collection psobjs = new Collection (); string result = ""; string[] servers = null; WSManConnectionInfo wmc = new WSManConnectionInfo(new Uri("http://xxx/powershell")); wmc.AuthenticatiOnMechanism= AuthenticationMechanism.Kerberos; wmc.ShellUri = "http://schemas.microsoft.com/powershell/Microsoft.Exchange"; using (Runspace runspace = RunspaceFactory.CreateRunspace(wmc)) { PowerShell powershell = PowerShell.Create(); if (runspace.RunspaceStateInfo.State == RunspaceState.Opened) { // do nothing } else { runspace.Open(); powershell.Runspace = runspace; } try { PSCommand command = new PSCommand(); command.AddScript("Get-DatabaseAvailabilityGroup -Identity " + dagName); powershell.Commands = command; psobjs = powershell.Invoke(); if (powershell.HadErrors == true) { result = "Failed - " + powershell.Streams.Error[0].ToString(); result = result.Replace("\"", "*"); } PSPropertyInfo serversTemp = null; foreach (PSObject psobj in psobjs) { serversTemp = psobj.Properties["servers"]; } string s_servers = serversTemp.Value.ToString(); servers = s_servers.Split(' '); } catch (Exception ex) { string fail = ex.Message; } } return servers; } private string parseServerResults(Collection serverObjs) // needs servername, totaldbs, activedbs, passivedbs, preferencecount (11,11,11,11), mounteddbs, dismounteddbs, dagname { // called independently with each server, first object is always the server name Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); int index = 0; string returnValue = ""; string serverName = ""; int totalDbs = 0; int activeDbs = 0; // whichever has activation preference 1 int passiveDbs = 0; // whichever has activation preference 2, 3 or 4 string activeCopyServerName = ""; int activatiOnPreferenceOne= 0; int activatiOnPreferenceTwo= 0; int activatiOnPreferenceThree= 0; int activatiOnPreferenceFour= 0; int mountedCount = 0; int dismountedCount = 0; string dagName = ""; string dagServerAndDatabaseName = ""; foreach (PSObject obj in serverObjs) { if (index == 0) { serverName = obj.ToString(); } totalDbs = (serverObjs.Count - 1); PSMemberInfoCollection props = obj.Properties; string currentPrimaryActivatiOnServer= ""; foreach (PSPropertyInfo prop in props) { if (prop.Name == "MountedOnServer") { currentPrimaryActivatiOnServer= prop.Value.ToString(); break; } } List propertyNames = new List (); foreach (PSPropertyInfo prop in props) { string result = prop.Name + " | " + prop.Value; if (prop.Name == "Mounted") { if (prop.Value.ToString() == "True") { if (currentPrimaryActivationServer.ToLower().StartsWith(serverName.ToLower())) { mountedCount++; } } else { dismountedCount++; } } else if (prop.Name == "MountedOnServer") { activeCopyServerName = prop.Value.ToString(); } else if (prop.Name == "ActivationPreference") { string arr = prop.Value.ToString(); string[] vals = arr.Split(']'); foreach (string val in vals) { if (val != "") { string valTemp = val; if (val.Contains("[")) { valTemp = val.Replace("[", ""); } string[] preference = valTemp.Split(','); string preferenceZero = preference[0].ToString().Trim(); string preferenceOne= preference[1].ToString().Trim(); if (preferenceZero.ToLower() == serverName.ToLower()) { if (preferenceOne== "1") { if (currentPrimaryActivationServer.ToLower().StartsWith(serverName.ToLower())) { activeDbs++; } else { passiveDbs++; } } else { if (!(currentPrimaryActivationServer.ToLower().StartsWith(serverName.ToLower()))) { passiveDbs++; } else { activeDbs++; } } switch (preferenceOne) { case "1": activationPreferenceOne++; break; case "2": activationPreferenceTwo++; break; case "3": activationPreferenceThree++; break; case "4": activationPreferenceFour++; break; default: break; } } } } } else if (prop.Name == "Server") { string activeCopyServerName2 = prop.Value.ToString(); } else if (prop.Name == "MasterServerOrAvailabilityGroup") { dagName = prop.Value.ToString(); } else if (prop.Name == "MailboxProvisioningAttributes") { dagServerAndDatabaseName = prop.Value.ToString(); } propertyNames.Add(prop.Name.ToString()); // cumulative count of the property names } index++; } stopwatch.Stop(); Console.WriteLine(serverName + " - " + stopwatch.Elapsed.ToString()); return returnValue = serverName + "|" + totalDbs + "|" + activeDbs + "|" + passiveDbs + "|" + activationPreferenceOne + "," + activationPreferenceTwo + "," + activationPreferenceThree + "," + activationPreferenceFour + "|" + mountedCount + "|" + dismountedCount + "|" + dagName; } } } '@ write-host "after here-string"; Add-Type -TypeDefinition $distribution -ReferencedAssemblies System.Collections, System.ComponentModel, System.Data, System.Drawing, System.Linq, System.Management.Automation, System.Security, System.Threading.Tasks, System.Windows.Forms, System.Threading, System.Collections.Concurrent, System.Security.Principal $dagDistribution = New-Object MultiThreading.dagDistribution; $val = $dagDistribution.get("dag2");
David Browne.. 7
你有两个问题.可能真的只有一个.默认情况下,Add-Type使用C#版本5编译器,这是Windows中包含的最新编译器.字符串插值$
是一个较新的功能.请参阅此答案Powershell Add-Type C#6.0.
其次,你的C#代码中有powershell转义字符,不应该存在.而是使用文字here-string来包含任意C#源.例如:
$distribution = @' namespace MultiThreading { .... } '@
C#没有"特殊"方式来引用.NET Framework类型,因此您必须为编译器提供代码所依赖的程序集列表.
如果在-ReferencedAssemblies参数中指定程序集的"短名称",则Add-Type将使用将使用当前的.NET Framework程序集.所以:
Add-Type -TypeDefinition $distribution -ReferencedAssemblies System.Data, System.Xml
如果需要无法以这种方式解析的程序集,则必须列出程序集FullName,并且Add-Type将尝试加载它.
您肯定希望避免在您的powershell代码中为.NET Framework程序集放置一个完整的AssemblyName,因为这可能会导致您的脚本在具有不同.NET Framework版本或.NET Core的计算机上运行时中断.
你有两个问题.可能真的只有一个.默认情况下,Add-Type使用C#版本5编译器,这是Windows中包含的最新编译器.字符串插值$
是一个较新的功能.请参阅此答案Powershell Add-Type C#6.0.
其次,你的C#代码中有powershell转义字符,不应该存在.而是使用文字here-string来包含任意C#源.例如:
$distribution = @' namespace MultiThreading { .... } '@
C#没有"特殊"方式来引用.NET Framework类型,因此您必须为编译器提供代码所依赖的程序集列表.
如果在-ReferencedAssemblies参数中指定程序集的"短名称",则Add-Type将使用将使用当前的.NET Framework程序集.所以:
Add-Type -TypeDefinition $distribution -ReferencedAssemblies System.Data, System.Xml
如果需要无法以这种方式解析的程序集,则必须列出程序集FullName,并且Add-Type将尝试加载它.
您肯定希望避免在您的powershell代码中为.NET Framework程序集放置一个完整的AssemblyName,因为这可能会导致您的脚本在具有不同.NET Framework版本或.NET Core的计算机上运行时中断.