diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f6c4fcc..82d7089a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +v2.2.0 +- Add ability to manage same windows server as installed without using WinRM +- Check for "core" version of PowerShell for command tweaks + v2.1.2 - Bug fix: Discovery not working against Windows servers - Bug fix: Issue running Discovery on Windows servers with one or more spaces in the path diff --git a/README.md b/README.md index c33d66c1..eff2cc88 100644 --- a/README.md +++ b/README.md @@ -361,7 +361,7 @@ CURL script to automate certificate store type creation can be found [here](Cert   ## Creating Certificate Stores and Scheduling Discovery Jobs -Please refer to the Keyfactor Command Reference Guide for information on creating certificate stores and scheduling Discovery jobs in Keyfactor Command. However, there are a few fields that are important to highlight here - Client Machine, Store Path (Creating Certificate Stores), Directories to search (Discovery jobs) and Extensions (Discovery jobs). For Linux orchestrated servers, "Client Machine" should be the DNS or IP address of the remote orchestrated server while "Store Path" is the full path and file name of the file based store, beginning with a forward slash (/). For Windows orchestrated servers, "Client Machine" should be of the format {protocol}://{dns-or-ip}:{port} where {protocol} is either http or https, {dns-or-ip} is the DNS or IP address of the remote orchestrated server, and {port} is the port where WinRM is listening, by convention usually 5985 for http and 5986 for https. "Store Path" is the full path and file name of the file based store, beginning with a drive letter (i.e. c:\). For example valid values for Client Machine and Store Path for Linux and Windows managed servers may look something like: +Please refer to the Keyfactor Command Reference Guide for information on creating certificate stores and scheduling Discovery jobs in Keyfactor Command. However, there are a few fields that are important to highlight here - Client Machine, Store Path (Creating Certificate Stores), and Directories to search (Discovery jobs) and Extensions (Discovery jobs). For Linux orchestrated servers, "Client Machine" should be the DNS or IP address of the remote orchestrated server while "Store Path" is the full path and file name of the file based store, beginning with a forward slash (/). For Windows orchestrated servers, "Client Machine" should be of the format {protocol}://{dns-or-ip}:{port} where {protocol} is either http or https, {dns-or-ip} is the DNS or IP address of the remote orchestrated server, and {port} is the port where WinRM is listening, by convention usually 5985 for http and 5986 for https. Alternately, entering the keyword "localhost" for "Client Machine" will point to the server where the orchestrator service is installed and WinRM WILL NOT be required. "Store Path" is the full path and file name of the file based store, beginning with a drive letter (i.e. c:\). For example valid values for Client Machine and Store Path for Linux and Windows managed servers may look something like: Linux: Client Machine - 127.0.0.1 or MyLinuxServerName; Store Path - /home/folder/path/storename.ext Windows: Client Machine - https://My.Server.Domain:5986; Store Path - c:\folder\path\storename.ext diff --git a/RemoteFile/RemoteHandlers/WinRMHandler.cs b/RemoteFile/RemoteHandlers/WinRMHandler.cs index 122fb579..354e23d9 100644 --- a/RemoteFile/RemoteHandlers/WinRMHandler.cs +++ b/RemoteFile/RemoteHandlers/WinRMHandler.cs @@ -8,6 +8,7 @@ using System; using System.Collections.Generic; using System.Management.Automation; +using System.Management.Automation.Remoting; using System.Management.Automation.Runspaces; using System.Net; using System.Text; @@ -31,10 +32,13 @@ internal WinRMHandler(string server, string serverLogin, string serverPassword) _logger.MethodEntry(LogLevel.Debug); Server = server; - connectionInfo = new WSManConnectionInfo(new System.Uri($"{Server}/wsman")); - if (!string.IsNullOrEmpty(serverLogin)) + if (Server.ToLower() != "localhost") { - connectionInfo.Credential = new PSCredential(serverLogin, new NetworkCredential(serverLogin, serverPassword).SecurePassword); + connectionInfo = new WSManConnectionInfo(new System.Uri($"{Server}/wsman")); + if (!string.IsNullOrEmpty(serverLogin)) + { + connectionInfo.Credential = new PSCredential(serverLogin, new NetworkCredential(serverLogin, serverPassword).SecurePassword); + } } _logger.MethodExit(LogLevel.Debug); @@ -46,11 +50,18 @@ public override void Initialize() try { - if (ApplicationSettings.UseNegotiate) + if (Server.ToLower() == "localhost") + { + runspace = RunspaceFactory.CreateRunspace(); + } + else { - connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Negotiate; + if (ApplicationSettings.UseNegotiate) + { + connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Negotiate; + } + runspace = RunspaceFactory.CreateRunspace(connectionInfo); } - runspace = RunspaceFactory.CreateRunspace(connectionInfo); runspace.Open(); } @@ -83,12 +94,6 @@ public override string RunCommand(string commandText, object[] parameters, bool using (PowerShell ps = PowerShell.Create()) { ps.Runspace = runspace; - - if (commandText.ToLower().IndexOf("keytool ") > -1) - { - commandText = ($"& '{commandText}").Replace("keytool", "keytool'"); - commandText = "echo '' | " + commandText; - } ps.AddScript(commandText); string displayCommand = commandText; @@ -100,7 +105,7 @@ public override string RunCommand(string commandText, object[] parameters, bool if (parameters != null) { - foreach(object parameter in parameters) + foreach (object parameter in parameters) ps.AddArgument(parameter); } @@ -120,7 +125,7 @@ public override string RunCommand(string commandText, object[] parameters, bool errors = null; break; } - + errors += (error + " "); } @@ -192,10 +197,12 @@ public override void UploadCertificateFile(string path, string fileName, byte[] _logger.MethodEntry(LogLevel.Debug); _logger.LogDebug($"UploadCertificateFile: {path} {fileName}"); + string cmdOption = RunCommand($@"$PSVersionTable.PSEdition", null, false, null).ToLower().Contains("core") ? "AsByteStream" : "Encoding Byte"; + string scriptBlock = $@" param($contents) - Set-Content {path + fileName} -Encoding Byte -Value $contents + Set-Content {path + fileName} -{cmdOption} -Value $contents "; object[] arguments = new object[] { certBytes }; @@ -211,7 +218,9 @@ public override byte[] DownloadCertificateFile(string path) _logger.LogDebug($"DownloadCertificateFile: {path}"); _logger.MethodExit(LogLevel.Debug); - return RunCommandBinary($@"Get-Content -Path ""{path}"" -Encoding Byte -Raw"); + string cmdOption = RunCommand($@"$PSVersionTable.PSEdition", null, false, null).ToLower().Contains("core") ? "AsByteStream" : "Encoding Byte"; + + return RunCommandBinary($@"Get-Content -Path ""{path}"" -{cmdOption} -Raw"); } public override void CreateEmptyStoreFile(string path, string linuxFilePermissions, string linuxFileOwner) diff --git a/readme_source.md b/readme_source.md index e426f3d9..76b97ac3 100644 --- a/readme_source.md +++ b/readme_source.md @@ -265,7 +265,7 @@ CURL script to automate certificate store type creation can be found [here](Cert   ## Creating Certificate Stores and Scheduling Discovery Jobs -Please refer to the Keyfactor Command Reference Guide for information on creating certificate stores and scheduling Discovery jobs in Keyfactor Command. However, there are a few fields that are important to highlight here - Client Machine, Store Path (Creating Certificate Stores), Directories to search (Discovery jobs) and Extensions (Discovery jobs). For Linux orchestrated servers, "Client Machine" should be the DNS or IP address of the remote orchestrated server while "Store Path" is the full path and file name of the file based store, beginning with a forward slash (/). For Windows orchestrated servers, "Client Machine" should be of the format {protocol}://{dns-or-ip}:{port} where {protocol} is either http or https, {dns-or-ip} is the DNS or IP address of the remote orchestrated server, and {port} is the port where WinRM is listening, by convention usually 5985 for http and 5986 for https. "Store Path" is the full path and file name of the file based store, beginning with a drive letter (i.e. c:\). For example valid values for Client Machine and Store Path for Linux and Windows managed servers may look something like: +Please refer to the Keyfactor Command Reference Guide for information on creating certificate stores and scheduling Discovery jobs in Keyfactor Command. However, there are a few fields that are important to highlight here - Client Machine, Store Path (Creating Certificate Stores), and Directories to search (Discovery jobs) and Extensions (Discovery jobs). For Linux orchestrated servers, "Client Machine" should be the DNS or IP address of the remote orchestrated server while "Store Path" is the full path and file name of the file based store, beginning with a forward slash (/). For Windows orchestrated servers, "Client Machine" should be of the format {protocol}://{dns-or-ip}:{port} where {protocol} is either http or https, {dns-or-ip} is the DNS or IP address of the remote orchestrated server, and {port} is the port where WinRM is listening, by convention usually 5985 for http and 5986 for https. Alternately, entering the keyword "localhost" for "Client Machine" will point to the server where the orchestrator service is installed and WinRM WILL NOT be required. "Store Path" is the full path and file name of the file based store, beginning with a drive letter (i.e. c:\). For example valid values for Client Machine and Store Path for Linux and Windows managed servers may look something like: Linux: Client Machine - 127.0.0.1 or MyLinuxServerName; Store Path - /home/folder/path/storename.ext Windows: Client Machine - https://My.Server.Domain:5986; Store Path - c:\folder\path\storename.ext