0

I am brand new to C# and am trying to run the following code into a button's click event.

using (PowerShell powerShell = PowerShell.Create())
        {
            powerShell.AddScript("Get-ComputerInfo | Select-Object CsDNSHostName,WindowsProductName, OSVersion, CSDomainRole, CSProcessors, OsProductType");
            powerShell.AddCommand("Out-String");


            Collection<PSObject> PSOutput = powerShell.Invoke();
            StringBuilder stringBuilder = new StringBuilder();
            foreach (PSObject pSObject in PSOutput)
            stringBuilder.AppendLine(pSObject.ToString());
            Tab2TxtBox2.Text = stringBuilder.ToString(); }

I will not be using Get-Computerinfo in my final script, I'm just using that commandlet to learn what I need to know. I will be using Get-AdComputer in my actual program. In this example I want to display CsDNSHostName,WindowsProductName, OSVersion, CSDomainRole, CSProcessors, and OsProductType in whichever textbox I want (I have six total boxes). I can display one item by using this code but don't know how to get the other items to display,

powerShell.AddScript("Get-ComputerInfo | Select-Object CsDNSHostName -expand CsDNSHostName -unique);

I hope someone here can help me.Thanks to anyone that is able to help.

2
  • You already defined a textbox (Tab2TxtBox2), and assigned it some text (Tab2TxtBox2.Text = stringBuilder.ToString();). In your question it is unclear why you cannot create another textbox (like, i.e.: Textbox3), and assign it some text, like: Textbox3.Text = 'Hello World!';. Commented Aug 20, 2022 at 16:58
  • Hello. Thanks for your reply. I want to know how to get CsDNSHostName,WindowsProductName, OSVersion, CSDomainRole, CSProcessors, and OsProductType from Get-ComputerInfo and then display each one in a textbox. I know to display just one, but not all of them. I can send you a screenshot of my app if it helps. Commented Aug 20, 2022 at 18:18

1 Answer 1

1

Just split your string into an array or list and then assign them to the textboxes.

            using (PowerShell powerShell = PowerShell.Create())
            {
                powerShell.AddScript("Get-ComputerInfo | Select-Object CsDNSHostName,WindowsProductName, OSVersion, CSDomainRole, CSProcessors, OsProductType");
                powerShell.AddCommand("Out-String");
                Collection<PSObject> PSOutput = powerShell.Invoke();
                StringBuilder stringBuilder = new StringBuilder();
                foreach (PSObject pSObject in PSOutput)
                    stringBuilder.AppendLine(pSObject.ToString());
                var stringarr = stringBuilder.ToString().Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                textBox1.Text = stringarr[0];
                textBox2.Text = stringarr[1];
                textBox3.Text = stringarr[2];
                textBox4.Text = stringarr[3];
                textBox5.Text = stringarr[4];
                textBox6.Text = stringarr[5];
            }



One quite note you might like for future usage.
If you add/change ConvertTo-Json + Newtonsoft.Json to your project you can easily phrase the string output (JSON Formated) to a class.

  1. Change Out-String to ConvertTo-Json
powerShell.AddCommand("ConvertTo-Json");
  1. Stop in debug once after Clipboard.SetText(stringBuilder.ToString());

  2. Use Visual Studio Menu -> Edit -> Paste Special -> Paste JSON as Classes



Full code to phrase your output to a class.

 private void button1_Click(object sender, EventArgs e)
        {
            using (PowerShell powerShell = PowerShell.Create())
            {
                powerShell.AddScript("Get-ComputerInfo | Select-Object CsDNSHostName,WindowsProductName, OSVersion, CSDomainRole, CSProcessors, OsProductType");
                powerShell.AddCommand("ConvertTo-Json");
                Collection<PSObject> PSOutput = powerShell.Invoke();
                StringBuilder stringBuilder = new StringBuilder();
                foreach (PSObject pSObject in PSOutput)
                {
                    stringBuilder.AppendLine(pSObject.ToString());
                }
#if DEBUG
                Clipboard.SetText(stringBuilder.ToString());
#endif
                Rootobject retval = JsonConvert.DeserializeObject<Rootobject>(stringBuilder.ToString());

                textBox1.Text = retval.CsDNSHostName.Trim();
                textBox2.Text = retval.WindowsProductName.Trim();
                textBox3.Text = retval.OsVersion.Trim();
                textBox4.Text = retval.CsDomainRole.ToString();
                textBox5.Text = retval.CsProcessors[0].Description.Trim();
                textBox6.Text = retval.OsProductType.ToString();
            }
        }


        public class Rootobject
        {
            public string CsDNSHostName { get; set; }
            public string WindowsProductName { get; set; }
            public string OsVersion { get; set; }
            public int CsDomainRole { get; set; }
            public Csprocessor[] CsProcessors { get; set; }
            public int OsProductType { get; set; }
        }

        public class Csprocessor
        {
            public string Name { get; set; }
            public string Manufacturer { get; set; }
            public string Description { get; set; }
            public int Architecture { get; set; }
            public int AddressWidth { get; set; }
            public int DataWidth { get; set; }
            public int MaxClockSpeed { get; set; }
            public int CurrentClockSpeed { get; set; }
            public int NumberOfCores { get; set; }
            public int NumberOfLogicalProcessors { get; set; }
            public object ProcessorID { get; set; }
            public object SocketDesignation { get; set; }
            public object ProcessorType { get; set; }
            public string Role { get; set; }
            public string Status { get; set; }
            public int CpuStatus { get; set; }
            public int Availability { get; set; }
        }

I usually use this methode to invoke a script.

public List<object> InvokeScript(string script)
        {

            List<object> pSDataStreams = new List<object>();
            using (PowerShell powerShell = PowerShell.Create())
            {
                powerShell.Streams.Information.DataAdding += (sender, e) => { pSDataStreams.Add(e.ItemAdded); };
                powerShell.Streams.Error.DataAdding += (sender, e) => { pSDataStreams.Add(e.ItemAdded); };
                powerShell.Streams.Debug.DataAdding += (sender, e) => { pSDataStreams.Add(e.ItemAdded); };
                powerShell.Streams.Progress.DataAdding += (sender, e) => { pSDataStreams.Add(e.ItemAdded); };
                powerShell.Streams.Verbose.DataAdding += (sender, e) => { pSDataStreams.Add(e.ItemAdded); };
                powerShell.Streams.Warning.DataAdding += (sender, e) => { pSDataStreams.Add(e.ItemAdded); };

                powerShell.AddScript(script);

                // powerShell.Streams.Information.d
                using (var outputCollection = new PSDataCollection<PSObject>())
                {
                    outputCollection.DataAdding += (sender, e) => { pSDataStreams.Add(e.ItemAdded); };
                    powerShell.Invoke(null, outputCollection);
                }
            }
            return pSDataStreams;
        }
Sign up to request clarification or add additional context in comments.

13 Comments

Thanks so much Naitwatch! This worked really well but the output was unexpected. When I run what you provided, I get the following,
Just use this string notation: var cn = "computername"; var ps = $@"Get-ADComputer -Identity ""{cn}"" -Properties *"; Please don't forget to upvote or accept answers if there somewhat usefull.
If there differences in the class check the underlying .net version of the powershell version used.
Edited the answer, you need to get powerShell.Streams.Error.DataAdding events. Use my method in a debug/view, phrase the content of the List<object>
See learn.microsoft.com/en-us/powershell/module/… especially -ErrorAction if you want to manipulate error behavior on the script level
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.