From 2372d5ca925e65cccf66697cd4e7c97a958698ff Mon Sep 17 00:00:00 2001 From: sk82jack Date: Tue, 4 Dec 2018 02:26:59 +0000 Subject: [PATCH] Fix and refactor code --- Tools/CreateBulkConnections_ConfCons2_6.ps1 | 259 +++++++++++++++----- 1 file changed, 191 insertions(+), 68 deletions(-) diff --git a/Tools/CreateBulkConnections_ConfCons2_6.ps1 b/Tools/CreateBulkConnections_ConfCons2_6.ps1 index f0f92a041..40d3b7449 100644 --- a/Tools/CreateBulkConnections_ConfCons2_6.ps1 +++ b/Tools/CreateBulkConnections_ConfCons2_6.ps1 @@ -1,60 +1,152 @@ ##################################### -# Author: David Sparer -# Summary: +# Authors: David Sparer & Jack Denton +# Summary: # This is intended to be a template for creating connections in bulk. This uses the serializers directly from the mRemoteNG binaries. # You will still need to create the connection info objects, but the library will handle serialization. It is expected that you # are familiar with PowerShell. If this is not the case, reach out to the mRemoteNG community for help. # Usage: -# Replace or modify the examples that are shown toward the end of the script to create your own connection info objects. +# Replace or modify the examples that are shown toward the end of the script to create your own connection info objects. ##################################### -$EncryptionKey = (Get-Credential -Message "Enter the encryption key you would like to use. This must match the encryption key used by the rest of the confCons file." -UserName "DontNeedUsername").Password -$PathToMrngFolder = "" - -if ($PathToMrngFolder -eq "") { - Write-Error -Message 'You must set the $PathToMrngFolder variable in this script to the folder which contains mRemoteNG.exe' +foreach ($Path in 'HKLM:\SOFTWARE\WOW6432Node\mRemoteNG', 'HKLM:\SOFTWARE\WOW6432Node\mRemoteNG') { + Try { + $mRNGPath = (Get-ItemProperty -Path $Path -Name InstallDir -ErrorAction Stop).InstallDir + break + } + Catch { + continue + } } +$null = [System.Reflection.Assembly]::LoadFile((Join-Path -Path $mRNGPath -ChildPath "mRemoteNG.exe")) +Add-Type -Path (Join-Path -Path $mRNGPath -ChildPath "BouncyCastle.Crypto.dll") -$assembly = [System.Reflection.Assembly]::LoadFile((Join-Path -Path $PathToMrngFolder -ChildPath "mRemoteNG.exe")) -$assembly = [System.Reflection.Assembly]::LoadFile((Join-Path -Path $PathToMrngFolder -ChildPath "BouncyCastle.Crypto.dll")) -function New-mRemoteNGXmlSerializer { + +function ConvertTo-mRNGSerializedXml { [CmdletBinding()] - param ( - [SecureString] - $EncryptionKey + Param ( + [Parameter(Mandatory)] + [mRemoteNG.Connection.ConnectionInfo[]] + $Xml, + + [Parameter()] + [pscredential] + $Credential = (Get-Credential -Message 'Enter the encryption key you would like to use. This must match the encryption key used by the rest of the confCons file.' -UserName $ENV:USERNAME) ) - PROCESS { - $cryptoProvider = New-Object -TypeName mRemoteNG.Security.SymmetricEncryption.AeadCryptographyProvider - $saveFilter = New-Object -TypeName mRemoteNG.Security.SaveFilter -ArgumentList @($false) - $xmlSerializer = New-Object -TypeName mRemoteNG.Config.Serializers.XmlConnectionNodeSerializer -ArgumentList @($cryptoProvider, $encryptionKey, $saveFilter) - Write-Output $xmlSerializer + $CryptoProvider = [mRemoteNG.Security.SymmetricEncryption.AeadCryptographyProvider]::new() + $SaveFilter = [mRemoteNG.Security.SaveFilter]::new() + $ConnectionNodeSerializer = [mRemoteNG.Config.Serializers.Xml.XmlConnectionNodeSerializer26]::new($CryptoProvider, $Credential.Password, $SaveFilter) + $XmlSerializer = [mRemoteNG.Config.Serializers.Xml.XmlConnectionsSerializer]::new($CryptoProvider, $ConnectionNodeSerializer) + + $RootNode = [mRemoteNG.Tree.Root.RootNodeInfo]::new('Connection') + foreach ($Node in $Xml) { + $RootNode.AddChild($Node) } + $XmlSerializer.Serialize($RootNode) } -function New-mRemoteNGConnectionInfo { +function New-mRNGConnection { [CmdletBinding()] - param () + Param ( + [Parameter(Mandatory)] + [string] + $Name, - PROCESS { - $connectionInfo = New-Object -TypeName mRemoteNG.Connection.ConnectionInfo - Write-Output $connectionInfo + [Parameter(Mandatory)] + [string] + $Hostname, + + [Parameter(Mandatory)] + [mRemoteNG.Connection.Protocol.ProtocolType] + $Protocol, + + [Parameter()] + [switch] + $InheritCredential, + + [Parameter()] + [mRemoteNG.Container.ContainerInfo] + $ParentContainer, + + [Parameter()] + [switch] + $PassThru + ) + + $Connection = [mRemoteNG.Connection.ConnectionInfo]@{ + Name = $Name + Hostname = $Hostname + Protocol = $Protocol + } + + if ($PSBoundParameters.ContainsKey('InheritCredential')) { + $Connection.Inheritance.Username = $true + $Connection.Inheritance.Domain = $true + $Connection.Inheritance.Password = $true + } + + if ($ParentContainer) { + $ParentContainer.AddChild($Connection) + + if ($PSBoundParameters.ContainsKey('PassThru')) { + $Connection + } + } + else { + $Connection } } -function New-mRemoteNGContainerInfo { +function New-mRNGContainer { [CmdletBinding()] - param () + Param ( + [Parameter(Mandatory)] + [string] + $Name, - PROCESS { - $connectionInfo = New-Object -TypeName mRemoteNG.Container.ContainerInfo - Write-Output $connectionInfo + [Parameter()] + [switch] + $InheritCredential, + + [Parameter()] + [mRemoteNG.Container.ContainerInfo] + $ParentContainer + ) + + $Container = [mRemoteNG.Container.ContainerInfo]@{ + Name = $Name } + + if ($PSBoundParameters.ContainsKey('InheritCredential')) { + $Container.Inheritance.Username = $true + $Container.Inheritance.Domain = $true + $Container.Inheritance.Password = $true + } + + if ($ParentContainer) { + $ParentContainer.AddChild($Container) + } + + $Container +} + +function Export-mRNGXml { + [CmdletBinding()] + param ( + [Parameter()] + [string] + $Path, + + [Parameter()] + [string] + $SerializedXml + ) + + $FilePathProvider = [mRemoteNG.Config.DataProviders.FileDataProvider]::new($Path) + $filePathProvider.Save($SerializedXml) } -# Setup the services needed to do serialization -$xmlSerializer = New-mRemoteNGXmlSerializer -EncryptionKey $EncryptionKey @@ -62,53 +154,84 @@ $xmlSerializer = New-mRemoteNGXmlSerializer -EncryptionKey $EncryptionKey # Example 1: serialize many connections, no containers # Here you can define the number of connection info objects to create # You can also provide a list of desired hostnames and iterate over those -$xml = "" -foreach($i in 1..5) -{ - $connectionInfo = New-mRemoteNGConnectionInfo - # Set connection info properties - $connectionInfo.Name = "server-$i" - $connectionInfo.Hostname = "some-win-server-$i" - $connectionInfo.Protocol = [mRemoteNG.Connection.Protocol.ProtocolType]::RDP - $connectionInfo.Inheritance.Username = $true - $connectionInfo.Inheritance.Domain = $true - $connectionInfo.Inheritance.Password = $true - - $serializedConnection = $xmlSerializer.SerializeConnectionInfo($connectionInfo).ToString() - $xml += $serializedConnection + [System.Environment]::NewLine +$Connections = foreach ($i in 1..5) { + # Create new connection + $Splat = @{ + Name = 'Server-{0:D2}' -f $i + Hostname = 'Server-{0:D2}' -f $i + Protocol = 'RDP' + InheritCredential = $true + } + New-mRNGConnection @Splat } -Write-Output $xml +# Serialize the connections +$SerializedXml = ConvertTo-mRNGSerializedXml -Xml $Connections + +# Write the XML to a file ready to import into mRemoteNG +Export-mRNGXml -Path "$ENV:APPDATA\mRemoteNG\PowerShellGenerated.xml" -SerializedXml $SerializedXml + +# Now open up mRemoteNG and press Ctrl+O and open up the exported XML file #---------------------------------------------------------------- # Example 2: serialize a container which has connections -# You can also create containers and add connections to them, which will be nested correctly when serialized -$xml = "" -$container = New-mRemoteNGContainerInfo -$container.Name = "ProductionServers" -$serializedContainer = $xmlSerializer.SerializeConnectionInfo($container) +# You can also create containers and add connections and containers to them, which will be nested correctly when serialized +# If you specify the ParentContainer parameter for new connections then there will be no output unless the PassThru parameter is also used -foreach($i in 1..3) -{ - $connectionInfo = New-mRemoteNGConnectionInfo +$ProdServers = New-mRNGContainer -Name 'ProdServers' - # Set connection info properties - $connectionInfo.Name = "server-$i" - $connectionInfo.Hostname = "some-linux-server-$i" - $connectionInfo.Protocol = [mRemoteNG.Connection.Protocol.ProtocolType]::SSH2 - $connectionInfo.Inheritance.Username = $true - $connectionInfo.Inheritance.Domain = $true - $connectionInfo.Inheritance.Password = $true - - # serialize the connection - $serializedConnection = $xmlSerializer.SerializeConnectionInfo($connectionInfo) - # add the connection to the container - $serializedContainer.Add($serializedConnection) +foreach ($i in 1..3) { + # Create new connection + $Splat = @{ + Name = 'Server-{0:D2}' -f $i + Hostname = 'Server-{0:D2}' -f $i + Protocol = 'RDP' + InheritCredential = $true + ParentContainer = $ProdServers + } + New-mRNGConnection @Splat } -# Call ToString() on the top-level container to get the XML of it and all its children -Write-Output $serializedContainer.ToString() \ No newline at end of file +$ProdWebServers = New-mRNGContainer -Name 'WebServers' -ParentContainer $ProdServers + +foreach ($i in 1..3) { + # Create new connection + $Splat = @{ + Name = 'WebServer-{0:D2}' -f $i + Hostname = 'WebServer-{0:D2}' -f $i + Protocol = 'SSH1' + InheritCredential = $true + ParentContainer = $ProdWebServers + } + New-mRNGConnection @Splat +} + +$DevServers = New-mRNGContainer -Name 'DevServers' + +foreach ($i in 1..3) { + # Create new connection + $Splat = @{ + Name = 'DevServer-{0:D2}' -f $i + Hostname = 'DevServer-{0:D2}' -f $i + Protocol = 'RDP' + InheritCredential = $true + ParentContainer = $DevServers + PassThru = $true + } + + # Specified the PassThru parameter in order to catch the connection and change a property + $Connection = New-mRNGConnection @Splat + $Connection.Resolution = 'FullScreen' +} + +# Serialize the container +$SerializedXml = ConvertTo-mRNGSerializedXml -Xml $ProdServers, $DevServers + +# Write the XML to a file ready to import into mRemoteNG +Export-mRNGXml -Path "$ENV:APPDATA\mRemoteNG\PowerShellGenerated.xml" -SerializedXml $SerializedXml + +# Now open up mRemoteNG and press Ctrl+O and open up the exported XML file