websitepanel/WebsitePanel/Sources/WebsitePanel.Providers.TerminalServices.Windows2012/Windows2012.cs
2015-02-27 06:47:53 -08:00

2565 lines
95 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright (c) 2015, Outercurve Foundation.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// - Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// - Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// - Neither the name of the Outercurve Foundation nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Runtime.Remoting;
using System.Text;
using System.Reflection;
using Microsoft.Win32;
using WebsitePanel.Providers.HostedSolution;
using WebsitePanel.Server.Utils;
using WebsitePanel.Providers.Utils;
using WebsitePanel.Providers.OS;
using WebsitePanel.Providers.Common;
using System.Management;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Collections.ObjectModel;
using System.DirectoryServices;
using System.Security.Cryptography.X509Certificates;
using System.Collections;
namespace WebsitePanel.Providers.RemoteDesktopServices
{
public class Windows2012 : HostingServiceProviderBase, IRemoteDesktopServices
{
#region Constants
private const string CapPath = @"RDS:\GatewayServer\CAP";
private const string RapPath = @"RDS:\GatewayServer\RAP";
private const string Computers = "Computers";
private const string AdDcComputers = "Domain Controllers";
private const string Users = "users";
private const string RdsGroupFormat = "rds-{0}-{1}";
private const string RdsModuleName = "RemoteDesktopServices";
private const string AddNpsString = "netsh nps add np name=\"\"{0}\"\" policysource=\"1\" processingorder=\"{1}\" conditionid=\"0x3d\" conditiondata=\"^5$\" conditionid=\"0x1fb5\" conditiondata=\"{2}\" conditionid=\"0x1e\" conditiondata=\"UserAuthType:(PW|CA)\" profileid=\"0x1005\" profiledata=\"TRUE\" profileid=\"0x100f\" profiledata=\"TRUE\" profileid=\"0x1009\" profiledata=\"0x7\" profileid=\"0x1fe6\" profiledata=\"0x40000000\"";
private const string WspAdministratorsGroupName = "WSP-Org-Administrators";
private const string WspAdministratorsGroupDescription = "WSP Org Administrators";
private const string RdsServersOU = "RDSServers";
private const string RDSHelpDeskComputerGroup = "Websitepanel-RDSHelpDesk-Computer";
private const string RDSHelpDeskGroup = "WSP-HelpDeskAdministrators";
private const string RDSHelpDeskGroupDescription = "WSP Help Desk Administrators";
#endregion
#region Properties
internal string PrimaryDomainController
{
get
{
return ProviderSettings["PrimaryDomainController"];
}
}
private string RootOU
{
get
{
return ProviderSettings["RootOU"];
}
}
private string CentralNpsHost
{
get
{
return ProviderSettings["CentralNPS"];
}
}
private IEnumerable<string> Gateways
{
get
{
return ProviderSettings["GWServrsList"].Split(';').Select(x => string.IsNullOrEmpty(x) ? x : x.Trim());
}
}
private bool CentralNps
{
get
{
return Convert.ToBoolean(ProviderSettings["UseCentralNPS"]);
}
}
private string RootDomain
{
get
{
return ServerSettings.ADRootDomain;
}
}
private string ConnectionBroker
{
get
{
return ProviderSettings["ConnectionBroker"];
}
}
#endregion
#region HostingServiceProvider methods
public override bool IsInstalled()
{
Server.Utils.OS.WindowsVersion version = WebsitePanel.Server.Utils.OS.GetVersion();
return version == WebsitePanel.Server.Utils.OS.WindowsVersion.WindowsServer2012 || version == WebsitePanel.Server.Utils.OS.WindowsVersion.WindowsServer2012R2;
}
public override string[] Install()
{
Runspace runSpace = null;
PSObject feature = null;
try
{
runSpace = OpenRunspace();
if (!IsFeatureInstalled("Desktop-Experience", runSpace))
{
feature = AddFeature(runSpace, "Desktop-Experience", true, false);
}
if (!IsFeatureInstalled("NET-Framework-Core", runSpace))
{
feature = AddFeature(runSpace, "NET-Framework-Core", true, false);
}
if (!IsFeatureInstalled("NET-Framework-45-Core", runSpace))
{
feature = AddFeature(runSpace, "NET-Framework-45-Core", true, false);
}
}
finally
{
CloseRunspace(runSpace);
}
return new string[]{};
}
public bool CheckRDSServerAvaliable(string hostname)
{
bool result = false;
var ping = new Ping();
var reply = ping.Send(hostname, 1000);
if (reply.Status == IPStatus.Success)
{
result = true;
}
return result;
}
#endregion
#region RDS Collections
public List<string> GetRdsCollectionSessionHosts(string collectionName)
{
var result = new List<string>();
Runspace runspace = null;
try
{
runspace = OpenRunspace();
Command cmd = new Command("Get-RDSessionHost");
cmd.Parameters.Add("CollectionName", collectionName);
cmd.Parameters.Add("ConnectionBroker", ConnectionBroker);
object[] errors;
var hosts = ExecuteShellCommand(runspace, cmd, false, out errors);
foreach (var host in hosts)
{
result.Add(GetPSObjectProperty(host, "SessionHost").ToString());
}
}
finally
{
CloseRunspace(runspace);
}
return result;
}
public bool AddRdsServersToDeployment(RdsServer[] servers)
{
var result = true;
Runspace runSpace = null;
try
{
runSpace = OpenRunspace();
foreach (var server in servers)
{
if (!ExistRdsServerInDeployment(runSpace, server))
{
AddRdsServerToDeployment(runSpace, server);
}
}
}
catch (Exception e)
{
result = false;
}
finally
{
CloseRunspace(runSpace);
}
return result;
}
public bool CreateCollection(string organizationId, RdsCollection collection)
{
var result = true;
Runspace runSpace = null;
try
{
runSpace = OpenRunspace();
var existingServers = GetServersExistingInCollections(runSpace);
existingServers = existingServers.Select(x => x.ToUpper()).Intersect(collection.Servers.Select(x => x.FqdName.ToUpper())).ToList();
if (existingServers.Any())
{
throw new Exception(string.Format("Server{0} {1} already added to another collection", existingServers.Count == 1 ? "" : "s", string.Join(" ,", existingServers.ToArray())));
}
foreach (var server in collection.Servers)
{
//If server will restart it will not be added to collection
//Do not install feature here
if (!ExistRdsServerInDeployment(runSpace, server))
{
AddRdsServerToDeployment(runSpace, server);
}
}
Command cmd = new Command("New-RDSessionCollection");
cmd.Parameters.Add("CollectionName", collection.Name);
cmd.Parameters.Add("SessionHost", collection.Servers.Select(x => x.FqdName).ToArray());
cmd.Parameters.Add("ConnectionBroker", ConnectionBroker);
if (!string.IsNullOrEmpty(collection.Description))
{
cmd.Parameters.Add("CollectionDescription", collection.Description);
}
var collectionPs = ExecuteShellCommand(runSpace, cmd, false).FirstOrDefault();
if (collectionPs == null)
{
throw new Exception("Collection not created");
}
EditRdsCollectionSettingsInternal(collection, runSpace);
var orgPath = GetOrganizationPath(organizationId);
if (!ActiveDirectoryUtils.AdObjectExists(GetComputerGroupPath(organizationId, collection.Name)))
{
//Create computer group
ActiveDirectoryUtils.CreateGroup(orgPath, GetComputersGroupName(collection.Name));
//todo Connection broker server must be added by default ???
//ActiveDirectoryUtils.AddObjectToGroup(GetComputerPath(ConnectionBroker), GetComputerGroupPath(organizationId, collection.Name));
}
CheckOrCreateHelpDeskComputerGroup();
if (!ActiveDirectoryUtils.AdObjectExists(GetUsersGroupPath(organizationId, collection.Name)))
{
//Create user group
ActiveDirectoryUtils.CreateGroup(orgPath, GetUsersGroupName(collection.Name));
}
var capPolicyName = GetPolicyName(organizationId, collection.Name, RdsPolicyTypes.RdCap);
var rapPolicyName = GetPolicyName(organizationId, collection.Name, RdsPolicyTypes.RdRap);
foreach (var gateway in Gateways)
{
if (!CentralNps)
{
CreateRdCapForce(runSpace, gateway, capPolicyName, collection.Name, new List<string> { GetUsersGroupName(collection.Name) });
}
CreateRdRapForce(runSpace, gateway, rapPolicyName, collection.Name, new List<string> { GetUsersGroupName(collection.Name) });
}
if (CentralNps)
{
CreateCentralNpsPolicy(runSpace, CentralNpsHost, capPolicyName, collection.Name, organizationId);
}
//add user group to collection
AddUserGroupsToCollection(runSpace, collection.Name, new List<string> { GetUsersGroupName(collection.Name) });
//add session servers to group
foreach (var rdsServer in collection.Servers)
{
if (!CheckLocalAdminsGroupExists(rdsServer.FqdName, runSpace))
{
CreateLocalAdministratorsGroup(rdsServer.FqdName, runSpace);
}
AddHelpDeskAdminsGroupToLocalAdmins(runSpace, rdsServer.FqdName);
AddComputerToCollectionAdComputerGroup(organizationId, collection.Name, rdsServer);
}
}
finally
{
CloseRunspace(runSpace);
}
return result;
}
public void EditRdsCollectionSettings(RdsCollection collection)
{
Runspace runSpace = null;
try
{
runSpace = OpenRunspace();
if (collection.Settings != null)
{
var errors = EditRdsCollectionSettingsInternal(collection, runSpace);
if (errors.Count > 0)
{
throw new Exception(string.Format("Settings not setted:\r\n{0}", string.Join("r\\n\\", errors.ToArray())));
}
}
}
finally
{
CloseRunspace(runSpace);
}
}
public List<RdsUserSession> GetRdsUserSessions(string collectionName)
{
Runspace runSpace = null;
var result = new List<RdsUserSession>();
try
{
runSpace = OpenRunspace();
result = GetRdsUserSessionsInternal(collectionName, runSpace);
}
finally
{
CloseRunspace(runSpace);
}
return result;
}
public void LogOffRdsUser(string unifiedSessionId, string hostServer)
{
Runspace runSpace = null;
try
{
runSpace = OpenRunspace();
object[] errors;
Command cmd = new Command("Invoke-RDUserLogoff");
cmd.Parameters.Add("HostServer", hostServer);
cmd.Parameters.Add("UnifiedSessionID", unifiedSessionId);
cmd.Parameters.Add("Force", true);
ExecuteShellCommand(runSpace, cmd, false, out errors);
if (errors != null && errors.Length > 0)
{
throw new Exception(string.Join("r\\n\\", errors.Select(e => e.ToString()).ToArray()));
}
}
finally
{
CloseRunspace(runSpace);
}
}
public List<string> GetServersExistingInCollections()
{
Runspace runSpace = null;
List<string> existingServers = new List<string>();
try
{
runSpace = OpenRunspace();
existingServers = GetServersExistingInCollections(runSpace);
}
finally
{
CloseRunspace(runSpace);
}
return existingServers;
}
public RdsCollection GetCollection(string collectionName)
{
RdsCollection collection =null;
Runspace runSpace = null;
try
{
runSpace = OpenRunspace();
Command cmd = new Command("Get-RDSessionCollection");
cmd.Parameters.Add("CollectionName", collectionName);
cmd.Parameters.Add("ConnectionBroker", ConnectionBroker);
var collectionPs = ExecuteShellCommand(runSpace, cmd, false).FirstOrDefault();
if (collectionPs != null)
{
collection = new RdsCollection();
collection.Name = Convert.ToString(GetPSObjectProperty(collectionPs, "CollectionName"));
collection.Description = Convert.ToString(GetPSObjectProperty(collectionPs, "CollectionDescription"));
}
}
finally
{
CloseRunspace(runSpace);
}
return collection;
}
public bool RemoveCollection(string organizationId, string collectionName, List<RdsServer> servers)
{
var result = true;
Runspace runSpace = null;
try
{
runSpace = OpenRunspace();
Command cmd = new Command("Remove-RDSessionCollection");
cmd.Parameters.Add("CollectionName", collectionName);
cmd.Parameters.Add("ConnectionBroker", ConnectionBroker);
cmd.Parameters.Add("Force", true);
ExecuteShellCommand(runSpace, cmd, false);
var capPolicyName = GetPolicyName(organizationId, collectionName, RdsPolicyTypes.RdCap);
var rapPolicyName = GetPolicyName(organizationId, collectionName, RdsPolicyTypes.RdRap);
foreach (var gateway in Gateways)
{
if (!CentralNps)
{
RemoveRdCap(runSpace, gateway, capPolicyName);
}
RemoveRdRap(runSpace, gateway, rapPolicyName);
}
if (CentralNps)
{
RemoveNpsPolicy(runSpace, CentralNpsHost, capPolicyName);
}
foreach(var server in servers)
{
RemoveComputerFromCollectionAdComputerGroup(organizationId, collectionName, server);
}
ActiveDirectoryUtils.DeleteADObject(GetComputerGroupPath(organizationId, collectionName));
ActiveDirectoryUtils.DeleteADObject(GetUsersGroupPath(organizationId, collectionName));
}
catch (Exception e)
{
result = false;
}
finally
{
CloseRunspace(runSpace);
}
return result;
}
public List<string> GetCollectionUsers(string collectionName)
{
return GetUsersToCollectionAdGroup(collectionName);
}
public bool SetUsersInCollection(string organizationId, string collectionName, List<string> users)
{
var result = true;
try
{
SetUsersToCollectionAdGroup(collectionName, organizationId, users);
}
catch (Exception e)
{
result = false;
Log.WriteWarning(e.ToString());
}
return result;
}
public void AddSessionHostServerToCollection(string organizationId, string collectionName, RdsServer server)
{
Runspace runSpace = null;
try
{
runSpace = OpenRunspace();
if (!ExistRdsServerInDeployment(runSpace, server))
{
AddRdsServerToDeployment(runSpace, server);
}
Command cmd = new Command("Add-RDSessionHost");
cmd.Parameters.Add("CollectionName", collectionName);
cmd.Parameters.Add("SessionHost", server.FqdName);
cmd.Parameters.Add("ConnectionBroker", ConnectionBroker);
ExecuteShellCommand(runSpace, cmd, false);
CheckOrCreateHelpDeskComputerGroup();
if (!CheckLocalAdminsGroupExists(server.FqdName, runSpace))
{
CreateLocalAdministratorsGroup(server.FqdName, runSpace);
}
AddHelpDeskAdminsGroupToLocalAdmins(runSpace, server.FqdName);
AddComputerToCollectionAdComputerGroup(organizationId, collectionName, server);
}
catch (Exception e)
{
}
finally
{
CloseRunspace(runSpace);
}
}
public void AddSessionHostServersToCollection(string organizationId, string collectionName, List<RdsServer> servers)
{
foreach (var server in servers)
{
AddSessionHostServerToCollection(organizationId, collectionName, server);
}
}
public void RemoveSessionHostServerFromCollection(string organizationId, string collectionName, RdsServer server)
{
Runspace runSpace = null;
try
{
runSpace = OpenRunspace();
Command cmd = new Command("Remove-RDSessionHost");
cmd.Parameters.Add("ConnectionBroker", ConnectionBroker);
cmd.Parameters.Add("SessionHost", server.FqdName);
cmd.Parameters.Add("Force", true);
ExecuteShellCommand(runSpace, cmd, false);
RemoveComputerFromCollectionAdComputerGroup(organizationId, collectionName, server);
}
finally
{
CloseRunspace(runSpace);
}
}
public void RemoveSessionHostServersFromCollection(string organizationId, string collectionName, List<RdsServer> servers)
{
foreach (var server in servers)
{
RemoveSessionHostServerFromCollection(organizationId, collectionName, server);
}
}
#endregion
public void SetRDServerNewConnectionAllowed(bool newConnectionAllowed, RdsServer server)
{
Runspace runSpace = null;
try
{
runSpace = OpenRunspace();
Command cmd = new Command("Set-RDSessionHost");
cmd.Parameters.Add("SessionHost", server.FqdName);
cmd.Parameters.Add("NewConnectionAllowed", string.Format("${0}", newConnectionAllowed.ToString()));
ExecuteShellCommand(runSpace, cmd, false);
}
catch (Exception e)
{
}
finally
{
CloseRunspace(runSpace);
}
}
#region Remote Applications
public string[] GetApplicationUsers(string collectionName, string applicationName)
{
Runspace runspace = null;
List<string> result = new List<string>();
try
{
runspace = OpenRunspace();
Command cmd = new Command("Get-RDRemoteApp");
cmd.Parameters.Add("CollectionName", collectionName);
cmd.Parameters.Add("ConnectionBroker", ConnectionBroker);
cmd.Parameters.Add("Alias", applicationName);
var application = ExecuteShellCommand(runspace, cmd, false).FirstOrDefault();
if (application != null)
{
var users = (string[])(GetPSObjectProperty(application, "UserGroups"));
if (users != null)
{
result.AddRange(users);
}
}
}
finally
{
CloseRunspace(runspace);
}
return result.ToArray();
}
public bool SetApplicationUsers(string collectionName, RemoteApplication remoteApp, string[] users)
{
Runspace runspace = null;
bool result = true;
try
{
Log.WriteWarning(string.Format("App alias: {0}\r\nCollection Name:{2}\r\nUsers: {1}", remoteApp.Alias, string.Join("; ", users), collectionName));
runspace = OpenRunspace();
Command cmd = new Command("Set-RDRemoteApp");
cmd.Parameters.Add("CollectionName", collectionName);
cmd.Parameters.Add("ConnectionBroker", ConnectionBroker);
cmd.Parameters.Add("DisplayName", remoteApp.DisplayName);
cmd.Parameters.Add("UserGroups", users);
cmd.Parameters.Add("Alias", remoteApp.Alias);
object[] errors;
ExecuteShellCommand(runspace, cmd, false, out errors).FirstOrDefault();
if (errors.Any())
{
Log.WriteWarning(string.Format("{0} adding users errors: {1}", remoteApp.DisplayName, string.Join("\r\n", errors.Select(e => e.ToString()).ToArray())));
}
else
{
Log.WriteWarning(string.Format("{0} users added successfully", remoteApp.DisplayName));
}
}
catch(Exception)
{
result = false;
}
finally
{
CloseRunspace(runspace);
}
return result;
}
public List<StartMenuApp> GetAvailableRemoteApplications(string collectionName)
{
var startApps = new List<StartMenuApp>();
Runspace runSpace = null;
try
{
runSpace = OpenRunspace();
Command cmd = new Command("Get-RDAvailableApp");
cmd.Parameters.Add("CollectionName", collectionName);
cmd.Parameters.Add("ConnectionBroker", ConnectionBroker);
var remoteApplicationsPS = ExecuteShellCommand(runSpace, cmd, false);
if (remoteApplicationsPS != null)
{
startApps.AddRange(remoteApplicationsPS.Select(CreateStartMenuAppFromPsObject));
}
}
finally
{
CloseRunspace(runSpace);
}
return startApps;
}
public List<RemoteApplication> GetCollectionRemoteApplications(string collectionName)
{
var remoteApps = new List<RemoteApplication>();
Runspace runSpace = null;
try
{
runSpace = OpenRunspace();
Command cmd = new Command("Get-RDRemoteApp");
cmd.Parameters.Add("CollectionName", collectionName);
cmd.Parameters.Add("ConnectionBroker", ConnectionBroker);
var remoteAppsPs = ExecuteShellCommand(runSpace, cmd, false);
if (remoteAppsPs != null)
{
remoteApps.AddRange(remoteAppsPs.Select(CreateRemoteApplicationFromPsObject));
}
}
finally
{
CloseRunspace(runSpace);
}
return remoteApps;
}
public bool AddRemoteApplication(string collectionName, RemoteApplication remoteApp)
{
var result = false;
Runspace runSpace = null;
try
{
runSpace = OpenRunspace();
Command cmd = new Command("New-RDRemoteApp");
cmd.Parameters.Add("CollectionName", collectionName);
cmd.Parameters.Add("ConnectionBroker", ConnectionBroker);
cmd.Parameters.Add("Alias", remoteApp.Alias);
cmd.Parameters.Add("DisplayName", remoteApp.DisplayName);
cmd.Parameters.Add("FilePath", remoteApp.FilePath);
cmd.Parameters.Add("ShowInWebAccess", remoteApp.ShowInWebAccess);
if (!string.IsNullOrEmpty(remoteApp.RequiredCommandLine))
{
cmd.Parameters.Add("CommandLineSetting", "Require");
cmd.Parameters.Add("RequiredCommandLine", remoteApp.RequiredCommandLine);
}
ExecuteShellCommand(runSpace, cmd, false);
result = true;
}
finally
{
CloseRunspace(runSpace);
}
return result;
}
public bool AddRemoteApplications(string collectionName, List<RemoteApplication> remoteApps)
{
var result = true;
foreach (var remoteApp in remoteApps)
{
result = AddRemoteApplication(collectionName, remoteApp) && result;
}
return result;
}
public bool RemoveRemoteApplication(string collectionName, RemoteApplication remoteApp)
{
var result = false;
Runspace runSpace = null;
try
{
runSpace = OpenRunspace();
Command cmd = new Command("Remove-RDRemoteApp");
cmd.Parameters.Add("CollectionName", collectionName);
cmd.Parameters.Add("ConnectionBroker", ConnectionBroker);
cmd.Parameters.Add("Alias", remoteApp.Alias);
cmd.Parameters.Add("Force", true);
ExecuteShellCommand(runSpace, cmd, false);
}
finally
{
CloseRunspace(runSpace);
}
return result;
}
#endregion
#region Gateaway (RD CAP | RD RAP)
internal void CreateCentralNpsPolicy(Runspace runSpace, string centralNpshost, string policyName, string collectionName, string organizationId)
{
var showCmd = new Command("netsh nps show np");
var showResult = ExecuteRemoteShellCommand(runSpace, centralNpshost, showCmd);
var processingOrders = showResult.Where(x => Convert.ToString(x).ToLower().Contains("processing order")).Select(x => Convert.ToString(x));
var count = 0;
foreach(var processingOrder in processingOrders)
{
var order = Convert.ToInt32(processingOrder.Remove(0, processingOrder.LastIndexOf("=") + 1).Replace(" ", ""));
if (order > count)
{
count = order;
}
}
var userGroupAd = ActiveDirectoryUtils.GetADObject(GetUsersGroupPath(organizationId, collectionName));
var userGroupSid = (byte[])ActiveDirectoryUtils.GetADObjectProperty(userGroupAd, "objectSid");
var addCmdString = string.Format(AddNpsString, policyName.Replace(" ", "_"), count + 1, ConvertByteToStringSid(userGroupSid));
Command addCmd = new Command(addCmdString);
var result = ExecuteRemoteShellCommand(runSpace, centralNpshost, addCmd);
}
internal void RemoveNpsPolicy(Runspace runSpace, string centralNpshost, string policyName)
{
var removeCmd = new Command(string.Format("netsh nps delete np {0}", policyName.Replace(" ", "_")));
var removeResult = ExecuteRemoteShellCommand(runSpace, centralNpshost, removeCmd);
}
internal void CreateRdCapForce(Runspace runSpace, string gatewayHost, string policyName, string collectionName, List<string> groups)
{
//New-Item -Path "RDS:\GatewayServer\CAP" -Name "Allow Admins" -UserGroups "Administrators@." -AuthMethod 1
//Set-Item -Path "RDS:\GatewayServer\CAP\Allow Admins\SessionTimeout" -Value 480 -SessionTimeoutAction 0
if (ItemExistsRemote(runSpace, gatewayHost, Path.Combine(CapPath, policyName)))
{
RemoveRdCap(runSpace, gatewayHost, policyName);
}
var userGroupParametr = string.Format("@({0})",string.Join(",", groups.Select(x => string.Format("\"{0}@{1}\"", x, RootDomain)).ToArray()));
Command rdCapCommand = new Command("New-Item");
rdCapCommand.Parameters.Add("Path", string.Format("\"{0}\"", CapPath));
rdCapCommand.Parameters.Add("Name", string.Format("\"{0}\"", policyName));
rdCapCommand.Parameters.Add("UserGroups", userGroupParametr);
rdCapCommand.Parameters.Add("AuthMethod", 1);
ExecuteRemoteShellCommand(runSpace, gatewayHost, rdCapCommand, RdsModuleName);
}
internal void RemoveRdCap(Runspace runSpace, string gatewayHost, string name)
{
RemoveItemRemote(runSpace, gatewayHost, string.Format(@"{0}\{1}", CapPath, name), RdsModuleName);
}
internal void CreateRdRapForce(Runspace runSpace, string gatewayHost, string policyName, string collectionName, List<string> groups)
{
//New-Item -Path "RDS:\GatewayServer\RAP" -Name "Allow Connections To Everywhere" -UserGroups "Administrators@." -ComputerGroupType 1
//Set-Item -Path "RDS:\GatewayServer\RAP\Allow Connections To Everywhere\PortNumbers" -Value 3389,3390
if (ItemExistsRemote(runSpace, gatewayHost, Path.Combine(RapPath, policyName)))
{
RemoveRdRap(runSpace, gatewayHost, policyName);
}
var userGroupParametr = string.Format("@({0})", string.Join(",", groups.Select(x => string.Format("\"{0}@{1}\"", x, RootDomain)).ToArray()));
var computerGroupParametr = string.Format("\"{0}@{1}\"", GetComputersGroupName(collectionName), RootDomain);
Command rdRapCommand = new Command("New-Item");
rdRapCommand.Parameters.Add("Path", string.Format("\"{0}\"", RapPath));
rdRapCommand.Parameters.Add("Name", string.Format("\"{0}\"", policyName));
rdRapCommand.Parameters.Add("UserGroups", userGroupParametr);
rdRapCommand.Parameters.Add("ComputerGroupType", 1);
rdRapCommand.Parameters.Add("ComputerGroup", computerGroupParametr);
object[] errors;
for (int i = 0; i < 3; i++)
{
Log.WriteWarning(string.Format("Adding RD RAP ... {0}\r\nGateway Host\t{1}\r\nUser Group\t{2}\r\nComputer Group\t{3}", i + 1, gatewayHost, userGroupParametr, computerGroupParametr));
ExecuteRemoteShellCommand(runSpace, gatewayHost, rdRapCommand, out errors, RdsModuleName);
if (errors == null || !errors.Any())
{
Log.WriteWarning("RD RAP Added Successfully");
break;
}
else
{
Log.WriteWarning(string.Join("\r\n", errors.Select(e => e.ToString()).ToArray()));
}
}
}
internal void RemoveRdRap(Runspace runSpace, string gatewayHost, string name)
{
RemoveItemRemote(runSpace, gatewayHost, string.Format(@"{0}\{1}", RapPath, name), RdsModuleName);
}
#endregion
#region Local Admins
public void SaveRdsCollectionLocalAdmins(List<OrganizationUser> users, List<string> hosts)
{
Runspace runspace = null;
try
{
runspace = OpenRunspace();
var index = ServerSettings.ADRootDomain.LastIndexOf(".");
var domainName = ServerSettings.ADRootDomain;
if (index > 0)
{
domainName = ServerSettings.ADRootDomain.Substring(0, index);
}
foreach (var hostName in hosts)
{
if (!CheckLocalAdminsGroupExists(hostName, runspace))
{
var errors = CreateLocalAdministratorsGroup(hostName, runspace);
if (errors.Any())
{
Log.WriteWarning(string.Join("\r\n", errors.Select(e => e.ToString()).ToArray()));
throw new Exception(string.Join("\r\n", errors.Select(e => e.ToString()).ToArray()));
}
}
var existingAdmins = GetExistingLocalAdmins(hostName, runspace).Select(e => e.ToLower());
var formUsers = users.Select(u => string.Format("{0}\\{1}", domainName, u.SamAccountName).ToLower());
var newUsers = users.Where(u => !existingAdmins.Contains(string.Format("{0}\\{1}", domainName, u.SamAccountName).ToLower()));
var removedUsers = existingAdmins.Where(e => !formUsers.Contains(e));
foreach (var user in newUsers)
{
AddNewLocalAdmin(hostName, user.SamAccountName, runspace);
}
foreach (var user in removedUsers)
{
RemoveLocalAdmin(hostName, user, runspace);
}
AddHelpDeskAdminsGroupToLocalAdmins(runspace, hostName);
}
}
finally
{
CloseRunspace(runspace);
}
}
public List<string> GetRdsCollectionLocalAdmins(string hostName)
{
Runspace runspace = null;
var result = new List<string>();
try
{
runspace = OpenRunspace();
if (CheckLocalAdminsGroupExists(hostName, runspace))
{
result = GetExistingLocalAdmins(hostName, runspace);
}
}
finally
{
CloseRunspace(runspace);
}
return result;
}
private bool CheckLocalAdminsGroupExists(string hostName, Runspace runspace)
{
var scripts = new List<string>
{
string.Format("net localgroup {0}", WspAdministratorsGroupName)
};
object[] errors = null;
var result = ExecuteRemoteShellCommand(runspace, hostName, scripts, out errors);
if (!errors.Any())
{
return true;
}
return false;
}
private object[] CreateLocalAdministratorsGroup(string hostName, Runspace runspace)
{
var scripts = new List<string>
{
string.Format("$cn = [ADSI]\"WinNT://{0}\"", hostName),
string.Format("$group = $cn.Create(\"Group\", \"{0}\")", WspAdministratorsGroupName),
"$group.setinfo()",
string.Format("$group.description = \"{0}\"", WspAdministratorsGroupDescription),
"$group.setinfo()"
};
object[] errors = null;
ExecuteRemoteShellCommand(runspace, hostName, scripts, out errors);
if (!errors.Any())
{
scripts = new List<string>
{
string.Format("$GroupObj = [ADSI]\"WinNT://{0}/Administrators\"", hostName),
string.Format("$GroupObj.Add(\"WinNT://{0}/{1}\")", hostName.ToLower().Replace(string.Format(".{0}", ServerSettings.ADRootDomain.ToLower()), ""), WspAdministratorsGroupName)
};
errors = null;
ExecuteRemoteShellCommand(runspace, hostName, scripts, out errors);
}
return errors;
}
private List<string> GetExistingLocalAdmins(string hostName, Runspace runspace)
{
var result = new List<string>();
var scripts = new List<string>
{
string.Format("net localgroup {0} | select -skip 6", WspAdministratorsGroupName)
};
object[] errors = null;
var exitingAdmins = ExecuteRemoteShellCommand(runspace, hostName, scripts, out errors);
if (!errors.Any())
{
foreach(var user in exitingAdmins.Take(exitingAdmins.Count - 2))
{
result.Add(user.ToString());
}
}
return result;
}
private object[] AddNewLocalAdmin(string hostName, string samAccountName, Runspace runspace)
{
var scripts = new List<string>
{
string.Format("$GroupObj = [ADSI]\"WinNT://{0}/{1}\"", hostName, WspAdministratorsGroupName),
string.Format("$GroupObj.Add(\"WinNT://{0}/{1}\")", ServerSettings.ADRootDomain, samAccountName)
};
object[] errors = null;
ExecuteRemoteShellCommand(runspace, hostName, scripts, out errors);
return errors;
}
private object[] RemoveLocalAdmin(string hostName, string user, Runspace runspace)
{
var userObject = user.Split('\\');
var scripts = new List<string>
{
string.Format("$GroupObj = [ADSI]\"WinNT://{0}/{1}\"", hostName, WspAdministratorsGroupName),
string.Format("$GroupObj.Remove(\"WinNT://{0}/{1}\")", userObject[0], userObject[1])
};
object[] errors = null;
ExecuteRemoteShellCommand(runspace, hostName, scripts, out errors);
return errors;
}
#endregion
#region RDS Help Desk
private string GetHelpDeskGroupPath(string groupName)
{
StringBuilder sb = new StringBuilder();
AppendProtocol(sb);
AppendDomainController(sb);
AppendCNPath(sb, groupName);
AppendOUPath(sb, RootOU);
AppendDomainPath(sb, RootDomain);
return sb.ToString();
}
private void CheckOrCreateHelpDeskComputerGroup()
{
if (!ActiveDirectoryUtils.AdObjectExists(GetHelpDeskGroupPath(RDSHelpDeskComputerGroup)))
{
ActiveDirectoryUtils.CreateGroup(GetRootOUPath(), RDSHelpDeskComputerGroup);
}
}
private void AddHelpDeskAdminsGroupToLocalAdmins(Runspace runspace, string hostName)
{
var helpDeskAdminsGroupPath = GetHelpDeskGroupPath(RDSHelpDeskGroup);
DirectoryEntry groupEntry = null;
if (!ActiveDirectoryUtils.AdObjectExists(helpDeskAdminsGroupPath))
{
ActiveDirectoryUtils.CreateGroup(GetRootOUPath(), RDSHelpDeskGroup);
groupEntry = ActiveDirectoryUtils.GetADObject(helpDeskAdminsGroupPath);
if (groupEntry.Properties.Contains("Description"))
{
groupEntry.Properties["Description"][0] = RDSHelpDeskGroupDescription;
}
else
{
groupEntry.Properties["Description"].Add(RDSHelpDeskGroupDescription);
}
groupEntry.CommitChanges();
}
if (groupEntry == null)
{
groupEntry = ActiveDirectoryUtils.GetADObject(helpDeskAdminsGroupPath);
}
var samAccountName = ActiveDirectoryUtils.GetADObjectProperty(groupEntry, "sAMAccountName");
var scripts = new List<string>
{
string.Format("$GroupObj = [ADSI]\"WinNT://{0}/{1}\"", hostName, WspAdministratorsGroupName),
string.Format("$GroupObj.Add(\"WinNT://{0}/{1}\")", ServerSettings.ADRootDomain, samAccountName)
};
object[] errors = null;
ExecuteRemoteShellCommand(runspace, hostName, scripts, out errors);
}
#endregion
#region SSL
public void InstallCertificate(byte[] certificate, string password, List<string> hostNames)
{
Runspace runspace = null;
try
{
var guid = Guid.NewGuid();
var x509Cert = new X509Certificate2(certificate, password, X509KeyStorageFlags.Exportable);
//var content = x509Cert.Export(X509ContentType.Pfx);
var filePath = SaveCertificate(certificate, guid);
runspace = OpenRunspace();
foreach (var hostName in hostNames)
{
var destinationPath = string.Format("\\\\{0}\\c$\\{1}.pfx", hostName, guid);
var errors = CopyCertificateFile(runspace, filePath, destinationPath);
if (!errors.Any())
{
errors = ImportCertificate(runspace, hostName, password, string.Format("c:\\{0}.pfx", guid), x509Cert.Thumbprint);
}
DeleteCertificateFile(destinationPath, runspace);
if (errors.Any())
{
Log.WriteWarning(string.Join("\r\n", errors.Select(e => e.ToString()).ToArray()));
throw new Exception(string.Join("\r\n", errors.Select(e => e.ToString()).ToArray()));
}
}
if (File.Exists(filePath))
{
File.Delete(filePath);
}
}
finally
{
CloseRunspace(runspace);
}
}
private object[] ImportCertificate(Runspace runspace, string hostName, string password, string certificatePath, string thumbprint)
{
var scripts = new List<string>
{
string.Format("$mypwd = ConvertTo-SecureString -String {0} -Force AsPlainText", password),
string.Format("Import-PfxCertificate FilePath \"{0}\" cert:\\localMachine\\my -Password $mypwd", certificatePath),
string.Format("$cert = Get-Item cert:\\LocalMachine\\My\\{0}", thumbprint),
string.Format("$path = (Get-WmiObject -class \"Win32_TSGeneralSetting\" -Namespace root\\cimv2\\terminalservices -Filter \"TerminalName='RDP-tcp'\").__path"),
string.Format("Set-WmiInstance -Path $path -argument @{0}", string.Format("{{SSLCertificateSHA1Hash=\"{0}\"}}", thumbprint))
};
object[] errors = null;
ExecuteRemoteShellCommand(runspace, hostName, scripts, out errors);
return errors;
}
private string SaveCertificate(byte[] certificate, Guid guid)
{
var filePath = string.Format("{0}{1}.pfx", Path.GetTempPath(), guid);
if (File.Exists(filePath))
{
File.Delete(filePath);
}
File.WriteAllBytes(filePath, certificate);
return filePath;
}
private object[] CopyCertificateFile(Runspace runspace, string filePath, string destinationPath)
{
var scripts = new List<string>
{
string.Format("Copy-Item \"{0}\" -Destination \"{1}\" -Force", filePath, destinationPath)
};
object[] errors = null;
ExecuteShellCommand(runspace, scripts, out errors);
return errors;
}
private object[] DeleteCertificateFile(string destinationPath, Runspace runspace)
{
var scripts = new List<string>
{
string.Format("Remove-Item -Path \"{0}\" -Force", destinationPath)
};
object[] errors = null;
ExecuteShellCommand(runspace, scripts, out errors);
return errors;
}
#endregion
private void AddRdsServerToDeployment(Runspace runSpace, RdsServer server)
{
Command cmd = new Command("Add-RDserver");
cmd.Parameters.Add("Server", server.FqdName);
cmd.Parameters.Add("Role", "RDS-RD-SERVER");
cmd.Parameters.Add("ConnectionBroker", ConnectionBroker);
ExecuteShellCommand(runSpace, cmd, false);
}
private bool ExistRdsServerInDeployment(Runspace runSpace, RdsServer server)
{
Command cmd = new Command("Get-RDserver");
cmd.Parameters.Add("Role", "RDS-RD-SERVER");
cmd.Parameters.Add("ConnectionBroker", ConnectionBroker);
var serversPs = ExecuteShellCommand(runSpace, cmd, false);
if (serversPs != null)
{
foreach (var serverPs in serversPs)
{
var serverName = Convert.ToString( GetPSObjectProperty(serverPs, "Server"));
if (string.Compare(serverName, server.FqdName, StringComparison.InvariantCultureIgnoreCase) == 0)
{
return true;
}
}
}
return false;
}
private void SetUsersToCollectionAdGroup(string collectionName, string organizationId, IEnumerable<string> users)
{
var usersGroupName = GetUsersGroupName(collectionName);
var usersGroupPath = GetUsersGroupPath(organizationId, collectionName);
var orgPath = GetOrganizationPath(organizationId);
var orgEntry = ActiveDirectoryUtils.GetADObject(orgPath);
var groupUsers = ActiveDirectoryUtils.GetGroupObjects(usersGroupName, "user", orgEntry);
//remove all users from group
foreach (string userPath in groupUsers)
{
ActiveDirectoryUtils.RemoveObjectFromGroup(userPath, usersGroupPath);
}
//adding users to group
foreach (var user in users)
{
var userPath = GetUserPath(organizationId, user);
if (ActiveDirectoryUtils.AdObjectExists(userPath))
{
var userObject = ActiveDirectoryUtils.GetADObject(userPath);
var samName = (string)ActiveDirectoryUtils.GetADObjectProperty(userObject, "sAMAccountName");
var userGroupsPath = GetUsersGroupPath(organizationId, collectionName);
ActiveDirectoryUtils.AddObjectToGroup(userPath, userGroupsPath);
}
}
}
private List<string> GetUsersToCollectionAdGroup(string collectionName)
{
var users = new List<string>();
var usersGroupName = GetUsersGroupName(collectionName);
foreach (string userPath in ActiveDirectoryUtils.GetGroupObjects(usersGroupName, "user"))
{
var userObject = ActiveDirectoryUtils.GetADObject(userPath);
var samName = (string)ActiveDirectoryUtils.GetADObjectProperty(userObject, "sAMAccountName");
users.Add(samName);
}
return users;
}
private void AddUserGroupsToCollection(Runspace runSpace, string collectionName, List<string> groups)
{
Command cmd = new Command("Set-RDSessionCollectionConfiguration");
cmd.Parameters.Add("CollectionName", collectionName);
cmd.Parameters.Add("UserGroup", groups);
cmd.Parameters.Add("ConnectionBroker", ConnectionBroker);
ExecuteShellCommand(runSpace, cmd, false).FirstOrDefault();
}
private void AddComputerToCollectionAdComputerGroup(string organizationId, string collectionName, RdsServer server)
{
var computerPath = GetComputerPath(server.Name, false);
var computerGroupName = GetComputersGroupName( collectionName);
if (!ActiveDirectoryUtils.AdObjectExists(computerPath))
{
computerPath = GetComputerPath(server.Name, true);
}
if (ActiveDirectoryUtils.AdObjectExists(computerPath))
{
var computerObject = ActiveDirectoryUtils.GetADObject(computerPath);
var samName = (string)ActiveDirectoryUtils.GetADObjectProperty(computerObject, "sAMAccountName");
if (!ActiveDirectoryUtils.IsComputerInGroup(samName, computerGroupName))
{
ActiveDirectoryUtils.AddObjectToGroup(computerPath, GetComputerGroupPath(organizationId, collectionName));
}
if (!ActiveDirectoryUtils.IsComputerInGroup(samName, RDSHelpDeskComputerGroup))
{
ActiveDirectoryUtils.AddObjectToGroup(computerPath, GetHelpDeskGroupPath(RDSHelpDeskComputerGroup));
}
}
SetRDServerNewConnectionAllowed(false, server);
}
private void RemoveComputerFromCollectionAdComputerGroup(string organizationId, string collectionName, RdsServer server)
{
var computerPath = GetComputerPath(server.Name, false);
var computerGroupName = GetComputersGroupName(collectionName);
if (!ActiveDirectoryUtils.AdObjectExists(computerPath))
{
computerPath = GetComputerPath(server.Name, true);
}
if (ActiveDirectoryUtils.AdObjectExists(computerPath))
{
var computerObject = ActiveDirectoryUtils.GetADObject(computerPath);
var samName = (string)ActiveDirectoryUtils.GetADObjectProperty(computerObject, "sAMAccountName");
if (ActiveDirectoryUtils.IsComputerInGroup(samName, computerGroupName))
{
ActiveDirectoryUtils.RemoveObjectFromGroup(computerPath, GetComputerGroupPath(organizationId, collectionName));
}
if (ActiveDirectoryUtils.AdObjectExists(GetHelpDeskGroupPath(RDSHelpDeskComputerGroup)))
{
if (ActiveDirectoryUtils.IsComputerInGroup(samName, RDSHelpDeskComputerGroup))
{
ActiveDirectoryUtils.RemoveObjectFromGroup(computerPath, GetHelpDeskGroupPath(RDSHelpDeskComputerGroup));
}
}
}
}
public bool AddSessionHostFeatureToServer(string hostName)
{
bool installationResult = false;
Runspace runSpace = null;
try
{
runSpace = OpenRunspace();
var feature = AddFeature(runSpace, hostName, "RDS-RD-Server", true, true);
installationResult = (bool)GetPSObjectProperty(feature, "Success");
}
finally
{
CloseRunspace(runSpace);
}
return installationResult;
}
public void MoveRdsServerToTenantOU(string hostName, string organizationId)
{
var tenantComputerGroupPath = GetTenantComputerGroupPath(organizationId);
if (!ActiveDirectoryUtils.AdObjectExists(tenantComputerGroupPath))
{
ActiveDirectoryUtils.CreateGroup(GetOrganizationPath(organizationId), RdsServersOU);
}
hostName = hostName.ToLower().Replace(string.Format(".{0}", ServerSettings.ADRootDomain.ToLower()), "");
var computerPath = GetComputerPath(hostName, true);
if(!ActiveDirectoryUtils.AdObjectExists(computerPath))
{
computerPath = GetComputerPath(hostName, false);
}
if (ActiveDirectoryUtils.AdObjectExists(computerPath))
{
var computerObject = ActiveDirectoryUtils.GetADObject(computerPath);
var samName = (string)ActiveDirectoryUtils.GetADObjectProperty(computerObject, "sAMAccountName");
if (!ActiveDirectoryUtils.IsComputerInGroup(samName, RdsServersOU))
{
DirectoryEntry group = new DirectoryEntry(tenantComputerGroupPath);
group.Invoke("Add", computerObject.Path);
group.CommitChanges();
}
}
}
public void RemoveRdsServerFromTenantOU(string hostName, string organizationId)
{
var tenantComputerGroupPath = GetTenantComputerGroupPath(organizationId);
hostName = hostName.ToLower().Replace(string.Format(".{0}", ServerSettings.ADRootDomain.ToLower()), "");
var tenantComputerPath = GetTenantComputerPath(hostName, organizationId);
var computerPath = GetComputerPath(hostName, true);
if (!ActiveDirectoryUtils.AdObjectExists(computerPath))
{
computerPath = GetComputerPath(hostName, false);
}
if (ActiveDirectoryUtils.AdObjectExists(computerPath))
{
var computerObject = ActiveDirectoryUtils.GetADObject(computerPath);
var samName = (string)ActiveDirectoryUtils.GetADObjectProperty(computerObject, "sAMAccountName");
if (ActiveDirectoryUtils.IsComputerInGroup(samName, RdsServersOU))
{
ActiveDirectoryUtils.RemoveObjectFromGroup(computerPath, tenantComputerGroupPath);
}
}
}
public bool CheckSessionHostFeatureInstallation(string hostName)
{
bool isInstalled = false;
Runspace runSpace = null;
try
{
runSpace = OpenRunspace();
Command cmd = new Command("Get-WindowsFeature");
cmd.Parameters.Add("Name", "RDS-RD-Server");
var feature = ExecuteRemoteShellCommand(runSpace, hostName, cmd).FirstOrDefault();
if (feature != null)
{
isInstalled = (bool) GetPSObjectProperty(feature, "Installed");
}
}
finally
{
CloseRunspace(runSpace);
}
return isInstalled;
}
public bool CheckServerAvailability(string hostName)
{
var ping = new Ping();
var ipAddress = GetServerIp(hostName);
var reply = ping.Send(ipAddress, 3000);
return reply != null && reply.Status == IPStatus.Success;
}
#region Helpers
private static string ConvertByteToStringSid(Byte[] sidBytes)
{
StringBuilder strSid = new StringBuilder();
strSid.Append("S-");
try
{
// Add SID revision.
strSid.Append(sidBytes[0].ToString());
// Next six bytes are SID authority value.
if (sidBytes[6] != 0 || sidBytes[5] != 0)
{
string strAuth = String.Format
("0x{0:2x}{1:2x}{2:2x}{3:2x}{4:2x}{5:2x}",
(Int16)sidBytes[1],
(Int16)sidBytes[2],
(Int16)sidBytes[3],
(Int16)sidBytes[4],
(Int16)sidBytes[5],
(Int16)sidBytes[6]);
strSid.Append("-");
strSid.Append(strAuth);
}
else
{
Int64 iVal = (Int32)(sidBytes[1]) +
(Int32)(sidBytes[2] << 8) +
(Int32)(sidBytes[3] << 16) +
(Int32)(sidBytes[4] << 24);
strSid.Append("-");
strSid.Append(iVal.ToString());
}
// Get sub authority count...
int iSubCount = Convert.ToInt32(sidBytes[7]);
int idxAuth = 0;
for (int i = 0; i < iSubCount; i++)
{
idxAuth = 8 + i * 4;
UInt32 iSubAuth = BitConverter.ToUInt32(sidBytes, idxAuth);
strSid.Append("-");
strSid.Append(iSubAuth.ToString());
}
}
catch
{
return "";
}
return strSid.ToString();
}
private StartMenuApp CreateStartMenuAppFromPsObject(PSObject psObject)
{
var remoteApp = new StartMenuApp
{
DisplayName = Convert.ToString(GetPSObjectProperty(psObject, "DisplayName")),
FilePath = Convert.ToString(GetPSObjectProperty(psObject, "FilePath")),
FileVirtualPath = Convert.ToString(GetPSObjectProperty(psObject, "FileVirtualPath"))
};
remoteApp.Alias = remoteApp.DisplayName;
return remoteApp;
}
private RemoteApplication CreateRemoteApplicationFromPsObject(PSObject psObject)
{
var remoteApp = new RemoteApplication
{
DisplayName = Convert.ToString(GetPSObjectProperty(psObject, "DisplayName")),
FilePath = Convert.ToString(GetPSObjectProperty(psObject, "FilePath")),
Alias = Convert.ToString(GetPSObjectProperty(psObject, "Alias")),
ShowInWebAccess = Convert.ToBoolean(GetPSObjectProperty(psObject, "ShowInWebAccess")),
Users = null
};
var requiredCommandLine = GetPSObjectProperty(psObject, "RequiredCommandLine");
remoteApp.RequiredCommandLine = requiredCommandLine == null ? null : requiredCommandLine.ToString();
var users = (string[])(GetPSObjectProperty(psObject, "UserGroups"));
if (users != null && users.Any())
{
remoteApp.Users = users;
}
return remoteApp;
}
internal IPAddress GetServerIp(string hostname, AddressFamily addressFamily = AddressFamily.InterNetwork)
{
var address = GetServerIps(hostname);
return address.FirstOrDefault(x => x.AddressFamily == addressFamily);
}
internal IEnumerable<IPAddress> GetServerIps(string hostname)
{
var address = Dns.GetHostAddresses(hostname);
return address;
}
internal void RemoveItem(Runspace runSpace, string path)
{
Command rdRapCommand = new Command("Remove-Item");
rdRapCommand.Parameters.Add("Path", path);
rdRapCommand.Parameters.Add("Force", true);
rdRapCommand.Parameters.Add("Recurse", true);
ExecuteShellCommand(runSpace, rdRapCommand, false);
}
internal void RemoveItemRemote(Runspace runSpace, string hostname, string path, params string[] imports)
{
Command rdRapCommand = new Command("Remove-Item");
rdRapCommand.Parameters.Add("Path", string.Format("\"{0}\"", path));
rdRapCommand.Parameters.Add("Force", "");
rdRapCommand.Parameters.Add("Recurse", "");
ExecuteRemoteShellCommand(runSpace, hostname, rdRapCommand, imports);
}
private string GetPolicyName(string organizationId, string collectionName, RdsPolicyTypes policyType)
{
string policyName = string.Format("{0}-", collectionName);
switch (policyType)
{
case RdsPolicyTypes.RdCap:
{
policyName += "RDCAP";
break;
}
case RdsPolicyTypes.RdRap:
{
policyName += "RDRAP";
break;
}
}
return policyName;
}
private string GetComputersGroupName(string collectionName)
{
return string.Format(RdsGroupFormat, collectionName, Computers.ToLowerInvariant());
}
private string GetUsersGroupName(string collectionName)
{
return string.Format(RdsGroupFormat, collectionName, Users.ToLowerInvariant());
}
internal string GetComputerGroupPath(string organizationId, string collection)
{
StringBuilder sb = new StringBuilder();
AppendProtocol(sb);
AppendDomainController(sb);
AppendCNPath(sb, GetComputersGroupName(collection));
AppendOUPath(sb, organizationId);
AppendOUPath(sb, RootOU);
AppendDomainPath(sb, RootDomain);
return sb.ToString();
}
internal string GetUsersGroupPath(string organizationId, string collection)
{
StringBuilder sb = new StringBuilder();
AppendProtocol(sb);
AppendDomainController(sb);
AppendCNPath(sb, GetUsersGroupName(collection));
AppendOUPath(sb, organizationId);
AppendOUPath(sb, RootOU);
AppendDomainPath(sb, RootDomain);
return sb.ToString();
}
private string GetUserPath(string organizationId, string loginName)
{
StringBuilder sb = new StringBuilder();
// append provider
AppendProtocol(sb);
AppendDomainController(sb);
AppendCNPath(sb, loginName);
AppendOUPath(sb, organizationId);
AppendOUPath(sb, RootOU);
AppendDomainPath(sb, RootDomain);
return sb.ToString();
}
private string GetRootOUPath()
{
StringBuilder sb = new StringBuilder();
// append provider
AppendProtocol(sb);
AppendDomainController(sb);
AppendOUPath(sb, RootOU);
AppendDomainPath(sb, RootDomain);
return sb.ToString();
}
private string GetOrganizationPath(string organizationId)
{
StringBuilder sb = new StringBuilder();
// append provider
AppendProtocol(sb);
AppendDomainController(sb);
AppendOUPath(sb, organizationId);
AppendOUPath(sb, RootOU);
AppendDomainPath(sb, RootDomain);
return sb.ToString();
}
private string GetComputerPath(string objName, bool domainController)
{
StringBuilder sb = new StringBuilder();
// append provider
AppendProtocol(sb);
AppendDomainController(sb);
AppendCNPath(sb, objName);
if (domainController)
{
AppendOUPath(sb, AdDcComputers);
}
else
{
AppendCNPath(sb, Computers);
}
AppendDomainPath(sb, RootDomain);
return sb.ToString();
}
private string GetTenantComputerPath(string objName, string organizationId)
{
StringBuilder sb = new StringBuilder();
AppendProtocol(sb);
AppendDomainController(sb);
AppendCNPath(sb, objName);
AppendCNPath(sb, RdsServersOU);
AppendOUPath(sb, organizationId);
AppendOUPath(sb, RootOU);
AppendDomainPath(sb, RootDomain);
return sb.ToString();
}
internal string GetTenantComputerGroupPath(string organizationId)
{
StringBuilder sb = new StringBuilder();
AppendProtocol(sb);
AppendDomainController(sb);
AppendCNPath(sb, RdsServersOU);
AppendOUPath(sb, organizationId);
AppendOUPath(sb, RootOU);
AppendDomainPath(sb, RootDomain);
return sb.ToString();
}
private static void AppendCNPath(StringBuilder sb, string organizationId)
{
if (string.IsNullOrEmpty(organizationId))
return;
sb.Append("CN=").Append(organizationId).Append(",");
}
private void AppendDomainController(StringBuilder sb)
{
sb.Append(PrimaryDomainController + "/");
}
private static void AppendProtocol(StringBuilder sb)
{
sb.Append("LDAP://");
}
private static void AppendOUPath(StringBuilder sb, string ou)
{
if (string.IsNullOrEmpty(ou))
return;
string path = ou.Replace("/", "\\");
string[] parts = path.Split('\\');
for (int i = parts.Length - 1; i != -1; i--)
sb.Append("OU=").Append(parts[i]).Append(",");
}
private static void AppendDomainPath(StringBuilder sb, string domain)
{
if (string.IsNullOrEmpty(domain))
return;
string[] parts = domain.Split('.');
for (int i = 0; i < parts.Length; i++)
{
sb.Append("DC=").Append(parts[i]);
if (i < (parts.Length - 1))
sb.Append(",");
}
}
#endregion
#region Windows Feature PowerShell
internal bool IsFeatureInstalled(string featureName, Runspace runSpace)
{
bool isInstalled = false;
Command cmd = new Command("Get-WindowsFeature");
cmd.Parameters.Add("Name", featureName);
var feature = ExecuteShellCommand(runSpace, cmd, false).FirstOrDefault();
if (feature != null)
{
isInstalled = (bool)GetPSObjectProperty(feature, "Installed");
}
return isInstalled;
}
internal bool IsFeatureInstalled(string hostName, string featureName, Runspace runSpace)
{
bool isInstalled = false;
Command cmd = new Command("Get-WindowsFeature");
cmd.Parameters.Add("Name", featureName);
var feature = ExecuteRemoteShellCommand(runSpace, hostName, cmd).FirstOrDefault();
if (feature != null)
{
isInstalled = (bool) GetPSObjectProperty(feature, "Installed");
}
return isInstalled;
}
internal PSObject AddFeature(Runspace runSpace, string featureName, bool includeAllSubFeature = true, bool restart = false)
{
Command cmd = new Command("Add-WindowsFeature");
cmd.Parameters.Add("Name", featureName);
if (includeAllSubFeature)
{
cmd.Parameters.Add("IncludeAllSubFeature", true);
}
if (restart)
{
cmd.Parameters.Add("Restart", true);
}
return ExecuteShellCommand(runSpace, cmd, false).FirstOrDefault();
}
internal PSObject AddFeature(Runspace runSpace, string hostName, string featureName, bool includeAllSubFeature = true, bool restart = false)
{
Command cmd = new Command("Add-WindowsFeature");
cmd.Parameters.Add("Name", featureName);
if (includeAllSubFeature)
{
cmd.Parameters.Add("IncludeAllSubFeature", "");
}
if (restart)
{
cmd.Parameters.Add("Restart", "");
}
return ExecuteRemoteShellCommand(runSpace, hostName, cmd).FirstOrDefault();
}
#endregion
#region PowerShell integration
private static InitialSessionState session = null;
internal virtual Runspace OpenRunspace()
{
Log.WriteStart("OpenRunspace");
if (session == null)
{
session = InitialSessionState.CreateDefault();
session.ImportPSModule(new string[] { "ServerManager", "RemoteDesktop", "RemoteDesktopServices" });
}
Runspace runSpace = RunspaceFactory.CreateRunspace(session);
//
runSpace.Open();
//
runSpace.SessionStateProxy.SetVariable("ConfirmPreference", "none");
Log.WriteEnd("OpenRunspace");
return runSpace;
}
internal void CloseRunspace(Runspace runspace)
{
try
{
if (runspace != null && runspace.RunspaceStateInfo.State == RunspaceState.Opened)
{
runspace.Close();
}
}
catch (Exception ex)
{
Log.WriteError("Runspace error", ex);
}
}
internal Collection<PSObject> ExecuteRemoteShellCommand(Runspace runSpace, string hostName, Command cmd, params string[] moduleImports)
{
object[] errors;
return ExecuteRemoteShellCommand(runSpace, hostName, cmd, out errors, moduleImports);
}
internal Collection<PSObject> ExecuteRemoteShellCommand(Runspace runSpace, string hostName, Command cmd, out object[] errors, params string[] moduleImports)
{
Command invokeCommand = new Command("Invoke-Command");
invokeCommand.Parameters.Add("ComputerName", hostName);
RunspaceInvoke invoke = new RunspaceInvoke();
string commandString = moduleImports.Any() ? string.Format("import-module {0};", string.Join(",", moduleImports)) : string.Empty;
commandString += cmd.CommandText;
if (cmd.Parameters != null && cmd.Parameters.Any())
{
commandString += " " +
string.Join(" ",
cmd.Parameters.Select(x => string.Format("-{0} {1}", x.Name, x.Value)).ToArray());
}
ScriptBlock sb = invoke.Invoke(string.Format("{{{0}}}", commandString))[0].BaseObject as ScriptBlock;
invokeCommand.Parameters.Add("ScriptBlock", sb);
return ExecuteShellCommand(runSpace, invokeCommand, false, out errors);
}
internal Collection<PSObject> ExecuteRemoteShellCommand(Runspace runSpace, string hostName, List<string> scripts, out object[] errors, params string[] moduleImports)
{
Command invokeCommand = new Command("Invoke-Command");
invokeCommand.Parameters.Add("ComputerName", hostName);
RunspaceInvoke invoke = new RunspaceInvoke();
string commandString = moduleImports.Any() ? string.Format("import-module {0};", string.Join(",", moduleImports)) : string.Empty;
commandString = string.Format("{0};{1}", commandString, string.Join(";", scripts.ToArray()));
ScriptBlock sb = invoke.Invoke(string.Format("{{{0}}}", commandString))[0].BaseObject as ScriptBlock;
invokeCommand.Parameters.Add("ScriptBlock", sb);
return ExecuteShellCommand(runSpace, invokeCommand, false, out errors);
}
internal Collection<PSObject> ExecuteShellCommand(Runspace runSpace, Command cmd)
{
return ExecuteShellCommand(runSpace, cmd, true);
}
internal Collection<PSObject> ExecuteShellCommand(Runspace runSpace, Command cmd, bool useDomainController)
{
object[] errors;
return ExecuteShellCommand(runSpace, cmd, useDomainController, out errors);
}
internal Collection<PSObject> ExecuteShellCommand(Runspace runSpace, Command cmd, out object[] errors)
{
return ExecuteShellCommand(runSpace, cmd, true, out errors);
}
internal Collection<PSObject> ExecuteShellCommand(Runspace runspace, List<string> scripts, out object[] errors)
{
Log.WriteStart("ExecuteShellCommand");
var errorList = new List<object>();
Collection<PSObject> results;
using (Pipeline pipeLine = runspace.CreatePipeline())
{
foreach (string script in scripts)
{
pipeLine.Commands.AddScript(script);
}
results = pipeLine.Invoke();
if (pipeLine.Error != null && pipeLine.Error.Count > 0)
{
foreach (object item in pipeLine.Error.ReadToEnd())
{
errorList.Add(item);
string errorMessage = string.Format("Invoke error: {0}", item);
Log.WriteWarning(errorMessage);
}
}
}
errors = errorList.ToArray();
Log.WriteEnd("ExecuteShellCommand");
return results;
}
internal Collection<PSObject> ExecuteShellCommand(Runspace runSpace, Command cmd, bool useDomainController,
out object[] errors)
{
Log.WriteStart("ExecuteShellCommand");
List<object> errorList = new List<object>();
if (useDomainController)
{
CommandParameter dc = new CommandParameter("DomainController", PrimaryDomainController);
if (!cmd.Parameters.Contains(dc))
{
cmd.Parameters.Add(dc);
}
}
Collection<PSObject> results = null;
// Create a pipeline
Pipeline pipeLine = runSpace.CreatePipeline();
using (pipeLine)
{
// Add the command
pipeLine.Commands.Add(cmd);
// Execute the pipeline and save the objects returned.
results = pipeLine.Invoke();
// Log out any errors in the pipeline execution
// NOTE: These errors are NOT thrown as exceptions!
// Be sure to check this to ensure that no errors
// happened while executing the command.
if (pipeLine.Error != null && pipeLine.Error.Count > 0)
{
foreach (object item in pipeLine.Error.ReadToEnd())
{
errorList.Add(item);
string errorMessage = string.Format("Invoke error: {0}", item);
Log.WriteWarning(errorMessage);
}
}
}
pipeLine = null;
errors = errorList.ToArray();
Log.WriteEnd("ExecuteShellCommand");
return results;
}
internal object GetPSObjectProperty(PSObject obj, string name)
{
return obj.Members[name].Value;
}
/// <summary>
/// Returns the identity of the object from the shell execution result
/// </summary>
/// <param name="result"></param>
/// <returns></returns>
internal string GetResultObjectIdentity(Collection<PSObject> result)
{
Log.WriteStart("GetResultObjectIdentity");
if (result == null)
throw new ArgumentNullException("result", "Execution result is not specified");
if (result.Count < 1)
throw new ArgumentException("Execution result is empty", "result");
if (result.Count > 1)
throw new ArgumentException("Execution result contains more than one object", "result");
PSMemberInfo info = result[0].Members["Identity"];
if (info == null)
throw new ArgumentException("Execution result does not contain Identity property", "result");
string ret = info.Value.ToString();
Log.WriteEnd("GetResultObjectIdentity");
return ret;
}
internal string GetResultObjectDN(Collection<PSObject> result)
{
Log.WriteStart("GetResultObjectDN");
if (result == null)
throw new ArgumentNullException("result", "Execution result is not specified");
if (result.Count < 1)
throw new ArgumentException("Execution result does not contain any object");
if (result.Count > 1)
throw new ArgumentException("Execution result contains more than one object");
PSMemberInfo info = result[0].Members["DistinguishedName"];
if (info == null)
throw new ArgumentException("Execution result does not contain DistinguishedName property", "result");
string ret = info.Value.ToString();
Log.WriteEnd("GetResultObjectDN");
return ret;
}
internal bool ItemExists(Runspace runSpace, string path)
{
Command testPathCommand = new Command("Test-Path");
testPathCommand.Parameters.Add("Path", path);
var testPathResult = ExecuteShellCommand(runSpace, testPathCommand, false).First();
var result = Convert.ToBoolean(testPathResult.ToString());
return result;
}
internal bool ItemExistsRemote(Runspace runSpace, string hostname,string path)
{
Command testPathCommand = new Command("Test-Path");
testPathCommand.Parameters.Add("Path", string.Format("\"{0}\"", path));
var testPathResult = ExecuteRemoteShellCommand(runSpace, hostname, testPathCommand, RdsModuleName).First();
var result = Convert.ToBoolean(testPathResult.ToString());
return result;
}
internal List<string> GetServersExistingInCollections(Runspace runSpace)
{
var existingHosts = new List<string>();
//var scripts = new List<string>();
//scripts.Add(string.Format("$sessions = Get-RDSessionCollection -ConnectionBroker {0}", ConnectionBroker));
//scripts.Add(string.Format("foreach($session in $sessions){{Get-RDSessionHost $session.CollectionName -ConnectionBroker {0}|Select SessionHost}}", ConnectionBroker));
//object[] errors;
//var sessionHosts = ExecuteShellCommand(runSpace, scripts, out errors);
//foreach(var host in sessionHosts)
//{
// var sessionHost = GetPSObjectProperty(host, "SessionHost");
// if (sessionHost != null)
// {
// existingHosts.Add(sessionHost.ToString());
// }
//}
return existingHosts;
}
internal List<string> EditRdsCollectionSettingsInternal(RdsCollection collection, Runspace runspace)
{
object[] errors;
Command cmd = new Command("Set-RDSessionCollectionConfiguration");
cmd.Parameters.Add("CollectionName", collection.Name);
cmd.Parameters.Add("ConnectionBroker", ConnectionBroker);
var properties = collection.Settings.GetType().GetProperties();
foreach(var prop in properties)
{
if (prop.Name.ToLower() != "id" && prop.Name.ToLower() != "rdscollectionid")
{
var value = prop.GetValue(collection.Settings, null);
if (value != null)
{
cmd.Parameters.Add(prop.Name, value);
}
}
}
ExecuteShellCommand(runspace, cmd, false, out errors);
if (errors != null)
{
return errors.Select(e => e.ToString()).ToList();
}
return new List<string>();
}
internal List<RdsUserSession> GetRdsUserSessionsInternal(string collectionName, Runspace runSpace)
{
var result = new List<RdsUserSession>();
var scripts = new List<string>();
scripts.Add(string.Format("Get-RDUserSession -ConnectionBroker {0} - CollectionName {1} | ft CollectionName, Username, UnifiedSessionId, SessionState, HostServer", ConnectionBroker, collectionName));
object[] errors;
Command cmd = new Command("Get-RDUserSession");
cmd.Parameters.Add("CollectionName", collectionName);
cmd.Parameters.Add("ConnectionBroker", ConnectionBroker);
var userSessions = ExecuteShellCommand(runSpace, cmd, false, out errors);
var properties = typeof(RdsUserSession).GetProperties();
foreach(var userSession in userSessions)
{
var session = new RdsUserSession
{
CollectionName = GetPSObjectProperty(userSession, "CollectionName").ToString(),
DomainName = GetPSObjectProperty(userSession, "DomainName").ToString(),
HostServer = GetPSObjectProperty(userSession, "HostServer").ToString(),
SessionState = GetPSObjectProperty(userSession, "SessionState").ToString(),
UnifiedSessionId = GetPSObjectProperty(userSession, "UnifiedSessionId").ToString(),
SamAccountName = GetPSObjectProperty(userSession, "UserName").ToString(),
};
session.IsVip = false;
session.UserName = GetUserFullName(session.DomainName, session.SamAccountName, runSpace);
result.Add(session);
}
return result;
}
private string GetUserFullName(string domain, string userName, Runspace runspace)
{
Command cmd = new Command("Get-WmiObject");
cmd.Parameters.Add("Class", "win32_useraccount");
cmd.Parameters.Add("Filter", string.Format("Domain = '{0}' AND Name = '{1}'", domain, userName));
var names = ExecuteShellCommand(runspace, cmd, false);
if (names.Any())
{
return names.First().Members["FullName"].Value.ToString();
}
return "";
}
#endregion
#region Server Info
public RdsServerInfo GetRdsServerInfo(string serverName)
{
var result = new RdsServerInfo();
Runspace runspace = null;
try
{
runspace = OpenRunspace();
result = GetServerInfo(runspace, serverName);
result.Status = GetRdsServerStatus(runspace, serverName);
}
finally
{
CloseRunspace(runspace);
}
return result;
}
public string GetRdsServerStatus(string serverName)
{
string result = "";
Runspace runspace = null;
try
{
runspace = OpenRunspace();
result = GetRdsServerStatus(runspace, serverName);
}
finally
{
CloseRunspace(runspace);
}
return result;
}
public void ShutDownRdsServer(string serverName)
{
Runspace runspace = null;
try
{
runspace = OpenRunspace();
var command = new Command("Stop-Computer");
command.Parameters.Add("ComputerName", serverName);
command.Parameters.Add("Force", true);
object[] errors = null;
ExecuteShellCommand(runspace, command, false, out errors);
if (errors.Any())
{
Log.WriteWarning(string.Join("\r\n", errors.Select(e => e.ToString()).ToArray()));
throw new Exception(string.Join("\r\n", errors.Select(e => e.ToString()).ToArray()));
}
}
finally
{
CloseRunspace(runspace);
}
}
public void RestartRdsServer(string serverName)
{
Runspace runspace = null;
try
{
runspace = OpenRunspace();
var command = new Command("Restart-Computer");
command.Parameters.Add("ComputerName", serverName);
command.Parameters.Add("Force", true);
object[] errors = null;
ExecuteShellCommand(runspace, command, false, out errors);
if (errors.Any())
{
Log.WriteWarning(string.Join("\r\n", errors.Select(e => e.ToString()).ToArray()));
throw new Exception(string.Join("\r\n", errors.Select(e => e.ToString()).ToArray()));
}
}
finally
{
CloseRunspace(runspace);
}
}
private RdsServerInfo GetServerInfo(Runspace runspace, string serverName)
{
var result = new RdsServerInfo();
Command cmd = new Command("Get-WmiObject");
cmd.Parameters.Add("Class", "Win32_Processor");
cmd.Parameters.Add("ComputerName", serverName);
object[] errors = null;
var psProcInfo = ExecuteShellCommand(runspace, cmd, false, out errors).First();
if (errors.Any())
{
Log.WriteWarning(string.Join("\r\n", errors.Select(e => e.ToString()).ToArray()));
return result;
}
cmd = new Command("Get-WmiObject");
cmd.Parameters.Add("Class", "Win32_OperatingSystem");
cmd.Parameters.Add("ComputerName", serverName);
var psMemoryInfo = ExecuteShellCommand(runspace, cmd, false, out errors).First();
if (errors.Any())
{
Log.WriteWarning(string.Join("\r\n", errors.Select(e => e.ToString()).ToArray()));
return result;
}
result.NumberOfCores = Convert.ToInt32(GetPSObjectProperty(psProcInfo, "NumberOfCores"));
result.MaxClockSpeed = Convert.ToInt32(GetPSObjectProperty(psProcInfo, "MaxClockSpeed"));
result.LoadPercentage = Convert.ToInt32(GetPSObjectProperty(psProcInfo, "LoadPercentage"));
result.MemoryAllocatedMb = Math.Round(Convert.ToDouble(GetPSObjectProperty(psMemoryInfo, "TotalVisibleMemorySize")) / 1024, 1);
result.FreeMemoryMb = Math.Round(Convert.ToDouble(GetPSObjectProperty(psMemoryInfo, "FreePhysicalMemory")) / 1024, 1);
result.Drives = GetRdsServerDriveInfo(runspace, serverName).ToArray();
return result;
}
private string GetRdsServerStatus (Runspace runspace, string serverName)
{
if (CheckServerAvailability(serverName))
{
if (CheckPendingReboot(runspace, serverName))
{
return "Online - Pending Reboot";
}
return "Online";
}
else
{
return "Unavailable";
}
}
private List<RdsServerDriveInfo> GetRdsServerDriveInfo(Runspace runspace, string serverName)
{
var result = new List<RdsServerDriveInfo>();
Command cmd = new Command("Get-WmiObject");
cmd.Parameters.Add("Class", "Win32_LogicalDisk");
cmd.Parameters.Add("Filter", "DriveType=3");
cmd.Parameters.Add("ComputerName", serverName);
object[] errors = null;
var psDrives = ExecuteShellCommand(runspace, cmd, false, out errors);
if (errors.Any())
{
Log.WriteWarning(string.Join("\r\n", errors.Select(e => e.ToString()).ToArray()));
return result;
}
foreach (var psDrive in psDrives)
{
var driveInfo = new RdsServerDriveInfo()
{
VolumeName = GetPSObjectProperty(psDrive, "VolumeName").ToString(),
DeviceId = GetPSObjectProperty(psDrive, "DeviceId").ToString(),
SizeMb = Math.Round(Convert.ToDouble(GetPSObjectProperty(psDrive, "Size"))/1024/1024, 1),
FreeSpaceMb = Math.Round(Convert.ToDouble(GetPSObjectProperty(psDrive, "FreeSpace"))/1024/1024, 1)
};
result.Add(driveInfo);
}
return result;
}
private bool CheckRDSServerAvaliability(string serverName)
{
var ping = new Ping();
var reply = ping.Send(serverName, 1000);
if (reply.Status == IPStatus.Success)
{
return true;
}
return false;
}
private bool CheckPendingReboot(Runspace runspace, string serverName)
{
if (CheckPendingReboot(runspace, serverName, @"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing", "RebootPending"))
{
return true;
}
if (CheckPendingReboot(runspace, serverName, @"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update", "RebootRequired"))
{
return true;
}
if (CheckPendingReboot(runspace, serverName, @"HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager", "PendingFileRenameOperations"))
{
return true;
}
return false;
}
private bool CheckPendingReboot(Runspace runspace, string serverName, string registryPath, string registryKey)
{
Command cmd = new Command("Get-ItemProperty");
cmd.Parameters.Add("Path", registryPath);
cmd.Parameters.Add("Name", registryKey);
cmd.Parameters.Add("ErrorAction", "SilentlyContinue");
var feature = ExecuteRemoteShellCommand(runspace, serverName, cmd).FirstOrDefault();
if (feature != null)
{
return true;
}
return false;
}
#endregion
}
}