(blog article under construction)
This post is part 1 of a series of 5 on writing C# applications using PowerShell modules of Skype for Business Server 2015.
I used Microsoft Visual Studio Community 2015 running Windows 10 and targeted Windows Desktop Application to .NET Framework 4.6.1.
We assume the “Skype for Business Server 2015 – Administrative Tools” are installed on your machine. they can be installed from the Skype for Business Server 2015 ISO file. After installation there is a directory with module “C:\Program Files\Common Files\Skype for Business Server 2015\ModulesSkypeForBusiness\SkypeForBusiness.psd1”.
In the App.config nothing special, just reference to .NET Framework 4.6.1.
App.config
1 2 3 4 5 6 |
<?xml version="1.0" encoding="utf-8"?> <configuration> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1"/> </startup> </configuration> |
Also in Program.cs nothing special, just launching the Form1. The code is intended for illustrating the PowerShell module integration concepts, therefor quite old-style monolithic.
Program.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
using System; using System.Windows.Forms; namespace PowerShell { static class Program { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } } } |
I have made a reference to the System.Management.Automation assembly.
I started adding in the user interface buttons “Create workspace” and “Get commands” and a ComboBox.
Form1.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
using System; using System.IO; using System.Windows.Forms; using System.Management.Automation; using System.Management.Automation.Runspaces; namespace PowerShell { public partial class Form1 : Form { InitialSessionState initial; Runspace runspace; System.Management.Automation.PowerShell ps; public Form1() { InitializeComponent(); button_Create_Workspace.Enabled = false; button_GetCommand.Enabled = false; comboBox_Commands.Items.Clear(); comboBox_Commands.Enabled = false; } |
When the “Create Workspace” button is clicked, a runspace is initialised and the Skype for Business Server 2015 module is loaded. This process may fail depending on your “Get-ExecutionPolicy -List” settings. More information is available on http://go.microsoft.com/fwlink/?LinkID=135170. On my development machine I performed a “Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope CurrentUser”.
Form1.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
private void button_Create_Workspace_Click(object sender, EventArgs e) { button_Create_Workspace.Enabled = false; try { initial = InitialSessionState.CreateDefault(); initial.ImportPSModule(new string[] { "C:\\Program Files\\Common Files\\Skype for Business Server 2015\\Modules\\SkypeForBusiness\\SkypeForBusiness.psd1" }); log("Creating runspace and importing module Skype for Business Server 2015...."); runspace = RunspaceFactory.CreateRunspace(initial); runspace.Open(); ps = System.Management.Automation.PowerShell.Create(); ps.Runspace = runspace; log("Runspace created"); button_GetCommand.Enabled = true; button_Create_Workspace.Enabled = false; } catch (Exception ex) { log("Error. Runspace could not be created"); MessageBox.Show(ex.Message); button_Create_Workspace.Enabled = true; } } |
When the runspace is created, we will perform our first PowerShell command. In our sample program we will perform a “Get-Command * -Module SkypeforBusiness -CommandType cmdlet” to retrieve the available cmdlets of Skype for Business module. Our pipe will consist of one command “Get-Command” and two parameters, hence the usage of methods AddCommand and AddParameter. The return object from Invoke() is a collection of PSObject instances that were written to the output stream during execution. PSObject is a wrapper class that adds PowerShell specific functionality around whatever the base object is. We will add all the retrieved cmdlets in our ComboxBox.
Form1.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
private void button_GetCommand_Click(object sender, EventArgs e) { comboBox_Commands.Items.Clear(); // "Get-Command * -Module SkypeforBusiness -CommandType cmdlet"; string command = "Get-Command"; dataGridView_Results.Rows.Clear(); dataGridView_Results.Refresh(); ps.AddCommand(command); ps.AddParameter("Module", "SkypeforBusiness"); ps.AddParameter("CommandType", "cmdlet"); log(String.Format("Performing {0}", command)); string resultName = ""; string resultModuleName = ""; foreach (PSObject result in ps.Invoke()) { try { if (result.Members["Name"].Value == null) { resultName = "null"; } else { resultName = result.Members["Name"].Value.ToString(); } if (result.Members["ModuleName"].Value == null) { resultModuleName = "null"; } else { resultModuleName = result.Members["ModuleName"].Value.ToString(); } comboBox_Commands.Items.Add(resultName); } catch (Exception ex) { MessageBox.Show(ex.Message); } } if (comboBox_Commands.Items.Count != 0) { log(String.Format("Get-Command completed normally.")); comboBox_Commands.Text = "Get-CsUser"; comboBox_Commands.Enabled = true; button_Execute.Enabled = true; } } |
In upcoming articles we will implement additional functionality and access the Skype for Business Server 2015 environment.