簡體   English   中英

在Powershell腳本中使用c#函數的正確語法是什么?

[英]What is the proper syntax for using c# functions in a powershell script?

我可以使用一個簡單的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 List<string> get(string dag)
            {
                DateTime start = DateTime.Now;

                var response = new ConcurrentBag<Collection<PSObject>>();
                var exceptions = new ConcurrentQueue<Exception>();

                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<string> returnValues = new List<string>();
                foreach (var item in response)
                {
                    string returnValue = parseServerResults(item);
                    returnValues.Add(returnValue);
                }

                returnValues.Sort();
                return returnValues;
            }

            private Collection<PSObject> runPowerShellScript(object server)
            {
                Collection<PSObject> psobjs = new Collection<PSObject>();
                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<PSObject> psobjs = new Collection<PSObject>();
                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<PSObject> 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<PSPropertyInfo> props = obj.Properties;

                string currentPrimaryActivationServer = "";
                foreach (PSPropertyInfo prop in props)
                {
                    if (prop.Name == "MountedOnServer")
                    {
                        currentPrimaryActivationServer = prop.Value.ToString();
                        break;
                    }
                }

                List<string> propertyNames = new List<string>();
                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");

你有兩個問題。 可能真的只是一個。 默認情況下,Add-Type使用C#版本5編譯器,這是Windows中包含的最新版本。 $的字符串插值是一個較新的功能。 請參閱此答案Powershell Add-Type C#6.0

其次,您的C#代碼中包含不應包含的Powershell轉義字符。 而是使用文字此處的字符串來包含任意C#源。 例如:

   $distribution = @'
    namespace MultiThreading
    {

        ....
    }

'@

C#沒有引用“ .NET Framework”類型的“特殊”方式,因此您必須向編譯器提供代碼所依賴的程序集列表。

如果在-ReferencedAssemblies參數中指定程序集的“短名稱”,則Add-Type將使用當前的.NET Framework程序集。 所以:

Add-Type -TypeDefinition $distribution -ReferencedAssemblies System.Data, System.Xml

如果需要無法通過這種方式解析的程序集,則必須列出程序集的全名,然后Add-Type將嘗試加載它。

您絕對要避免在Powershell代碼中放置.NET Framework程序集的完整AssemblyName,因為當在具有不同.NET Framework版本或.NET Core的計算機上運行時,這可能會導致腳本中斷。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM