SimpleEnv.psm1
Write-Verbose 'Importing from [C:\Users\chanc_000\Source\SimpleEnv\SimpleEnv\classes]' Write-Verbose 'Importing from [C:\Users\chanc_000\Source\SimpleEnv\SimpleEnv\private]' Write-Verbose 'Importing from [C:\Users\chanc_000\Source\SimpleEnv\SimpleEnv\public]' # .\Pre-Module.ps1 $Script:Configuration = @{ ConfigFilePath = "$Env:USERPROFILE/SimpleENV.json" } function ClearEnvironment { $script:Environment = @{ SimpleEnvVersion = '' EnvironmentInfo = @{ } Servers = @() } $Environment.SimpleEnvVersion = [string]$MyInvocation.MyCommand.Module.Version } ClearEnvironment # .\classes\SimpleEnvServer.ps1 class SimpleEnvServer { [string] $Name [string] $ComputerName [string] $Environment [string[]] $Roles = @() [string[]] $Tags = @() [hashtable] $Properties = @{ } } # .\public\Add-SimpleEnvServer.ps1 function Add-SimpleEnvServer { <# .SYNOPSIS Adds a SimpleEnvServer object to the loaded environment, and optionally save the changes back to the environment config. .PARAMETER ServerObject The [SimpleEnvServer] object to add. .PARAMETER Save Save changes back to the environment config file at the end of pipeline exectution. .EXAMPLE PS> (1..4) | %{New-SimpleEnvServer -Name "TestServer_$_"} | Add-SimpleEnvServer -Save Creates new SimpleEnv Servers named: Test_1,Test_2,Test_3,Test_4 and adds them to the loaded environment, then saves the changes back to the backing JSON file. #> [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'low')] param ( # SimpleEnvServer object [Parameter(Mandatory = $true, ValueFromPipeline = $true)] [object] $ServerObject, # [Parameter(Mandatory = $false)] [switch] $Save ) process { $server = [SimpleEnvServer]$ServerObject if ($PSCmdlet.ShouldProcess($server.Name, "Add to the existing environment?")) { $script:Environment.Servers += $server } } end { if ($Save.IsPresent -and $PSCmdlet.ShouldProcess( "Save changes to the existing environment?") ) { $SaveArgs = @{ Verbose = $Verbose } Save-SimpleEnv @SaveArgs } } } # .\public\Clear-SimpleEnv.ps1 function Clear-SimpleEnv { <# .Description Resets the in-memory SimpleEnv to a blank environment. .example PS> Clear-SimpleEnv #> [CmdletBinding()] param () Write-Verbose "Setting environment to default." ClearEnvironment } # .\public\Export-SimpleEnv.ps1 function Export-SimpleEnv { <# .description Writes the current SimpleEnv to a JSON file (with utf8 encoding). .parameter FilePath The Filepath to write too. .PARAMETER Force Overwrites existing file without confirmation .example PS> Export-SimpleEnv -FilePath '~\desktop\MyEnvironment.SimpleEnv.json' #> [CmdletBinding()] param ( # Path to Json file [Parameter(Mandatory = $true, ParameterSetName = "json", ValueFromPipelineByPropertyName = $true )] [alias("path")] [string] $FilePath, # [Parameter()] [switch] $Force ) $FileParams = @{ FilePath = $FilePath Encoding = 'utf8' } if ($Force.IsPresent) { $FileParams['Force'] = $true } else { $FileParams['NoClobber'] = $true } $script:Environment | ConvertTo-Json -Depth 5 | Out-File @FileParams } # .\public\Get-SimpleEnv.ps1 function Get-SimpleEnv { <# .Synopsis Get the entire stored simpleEnv as an object. .Parameter Full Get the entire stored simpleEnv as an object. .EXAMPLE PS> Get-SimpleEnv Get the entire stored simpleEnv as an object. .EXAMPLE PS> Get-SimpleEnv -Server Get the list of all server #> [CmdletBinding(DefaultParameterSetName = 'Full')] param ( # [Parameter(Mandatory = $true, ParameterSetName = 'Full')] [switch] $Full, [Parameter(Mandatory = $true, ParameterSetName = 'servers')] [switch] $Servers#, # [Parameter(Mandatory = $false, ParameterSetName = 'info')] # [switch] # $EnvironmentInfo ) begin { } process { if ($PSCmdlet.ParameterSetName -eq 'Full') { $script:Environment } elseif ($PSCmdlet.ParameterSetName -eq 'servers') { $script:Environment.Servers } elseif ($PSCmdlet.ParameterSetName -eq 'info') { $script:Environment.EnvironmentInfo } } end { } } # .\public\Get-SimpleEnvConfiguration.ps1 function Get-SimpleEnvConfiguration { <# .description Returns the current SimpleEnv configuration as a hashtable. .PARAMETER All Returns the full configuration .PARAMETER FilePath Returns only the FilePath of the backing JSON file. .example PS> Get-SimpleEnvConfiguration #> [CmdletBinding(DefaultParameterSetName = 'all')] [OutPutType([hashtable], ParameterSetName = 'all')] [OutPutType([string], ParameterSetName = 'filepath')] param ( [Parameter(ParameterSetName = 'all')] [switch] $All, [Parameter(ParameterSetName = 'filepath')] [switch] $FilePath ) if ($PSCmdlet.ParameterSetName -eq 'all') { return $Script:Configuration } else { if ($FilePath.IsPresent) { $Script:Configuration.ConfigFilePath } } } # .\public\Get-SimpleEnvServer.ps1 function Get-SimpleEnvServer { <# .description Retrieves the specified servers from the loaded SimpleEnv. .parameter Name Selects servers with a matching name, wildcard patterns are supported. .parameter Role Select Servers that have a Role that matches the wildcard pattern. .parameter Tag Select Servers that have a tag that matches the wildcard pattern. .parameter Environment Selects servers with a matching Environment, wildcard patterns are supported. .parameter All Return all servers. .parameter JustComputerName Return only the ComputerName(s) of the selected servers. .example PS> Get-SimpleEnvServer Name ComputerName Tags Properties ---- -------- ---- ---------- DevOps DevOps.test.env.com {dev, 2019, infrastructure, ops} {DistinguishedName} Dev-box Dev-box.test.env.com {dev, 2012r2, developer} {DistinguishedName} .example PS> Get-Server -Name *ops Name ComputerName Tags Properties ---- -------- ---- ---------- DevOps DevOps.test.env.com {dev, 2019, infrastructure, ops} {DistinguishedName} .example PS> Get-Server -Tag 2012* Name ComputerName Tags Properties ---- -------- ---- ---------- Dev-box Dev-box.test.env.com {dev, 2012r2, developer} {DistinguishedName} .example PS> Get-Server -Tag 2012* -JustComputerName Dev-box.test.env.com #> [CmdletBinding(DefaultParameterSetName = 'all')] param ( # [Parameter(Mandatory = $false, ParameterSetName = 'filtered', Position = 0)] [ValidateNotNullOrEmpty()] [SupportsWildcards()] [string] $Name, # [Parameter(Mandatory = $false, ParameterSetName = 'filtered')] [ValidateNotNullOrEmpty()] [SupportsWildcards()] [string] $Role, # [Parameter(Mandatory = $false, ParameterSetName = 'filtered')] [ValidateNotNullOrEmpty()] [SupportsWildcards()] [string] $Tag, # [Parameter(Mandatory = $false, ParameterSetName = 'filtered')] [ValidateNotNullOrEmpty()] [SupportsWildcards()] [string] $Environment, # Parameter help description [Parameter(Mandatory = $false, ParameterSetName = 'all')] [Parameter(Mandatory = $false, ParameterSetName = 'filtered')] [Alias('DnsName')] [switch] $JustComputerName, # Parameter help description [Parameter(Mandatory = $false, ParameterSetName = 'all')] [switch] $All ) begin { if ($script:Environment.Servers.count -eq 0) { Write-Warning -Message ("No servers in environment [{0}] Try importing another configuration, or adding a server." -f $Script:Configuration.ConfigFilePath) } [bool] $SkipName = (-not $PSBoundParameters.ContainsKey('Name')) [bool] $SkipTags = (-not $PSBoundParameters.ContainsKey('tag')) [bool] $SkipRoles = (-not $PSBoundParameters.ContainsKey('role')) [bool] $SkipEnv = (-not $PSBoundParameters.ContainsKey('Environment')) filter OutputFormat { if ($JustComputerName.IsPresent) { $Psitem.ComputerName } else { $Psitem } } } Process { $Servers = if ($PSCmdlet.ParameterSetName -like 'all') { $script:Environment.Servers } else { $script:Environment.Servers | Where-Object { ($SkipName -or ($_.Name -like $Name )) } | Where-Object { ($SkipTags -or ($_.Tags -like $Tag )) } | Where-Object { ($SkipRoles -or ($_.Roles -like $Role )) } | Where-Object { ($SkipEnv -or ($_.Environment -like $Environment )) } } Write-Verbose "Found $($Servers.count) servers." $Servers | OutputFormat } end { } } Set-Alias -Name 'Get-Server' -Value Get-SimpleEnvServer # .\public\Import-SimpleEnv.ps1 function Import-SimpleEnv { <# .SYNOPSIS Imports the specified Json file into the currently loaded SimpleEnv, however changes are still persisted back to the oridginal file. .PARAMETER FilePath Path to the SimpleENV json file to import. .PARAMETER ClearExisting Remove existing servers before importing, instead of combining the environments. .EXAMPLE PS> Import-SimpleEnv -FilePath Test.simpleenv.json -ClearExisting Should only have the servers in 'Test.simpleenv.json' loaded. #> [CmdletBinding()] param ( # Path to Json file [Parameter(Mandatory = $true, ParameterSetName = "json", ValueFromPipelineByPropertyName = $true )] [alias("path")] [string] $FilePath, # [Parameter()] [switch] $ClearExisting ) begin { #$ImportProperties = [SimpleEnvServer].DeclaredProperties.Name if ($ClearExisting.IsPresent) { $script:Environment.Servers.Clear() } function ObjToShallowhashtable($object) { if ($null -ne $object) { $props = $object $PropTable = @{ } $Keys = $props | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty Name $Keys | ForEach-Object { $PropTable.$_ = $props.$_ } $PropTable } else { return @{ } } } } process { $temp = Get-Content -Path $Filepath -Raw | ConvertFrom-Json # Reset-SimpleEnv $temp.Servers | ForEach-Object { $Srv = $_ if ($null -ne $Srv.Properties) { $srv.Properties = ObjToShallowhashtable -object $Srv.Properties } } $Temp.Servers | New-SimpleEnvServer | Add-SimpleEnvServer if ($null -ne $temp.EnvironmentInfo) { $script:Environment.EnvironmentInfo = ObjToShallowhashtable -object $Temp.EnvironmentInfo } elseif ($null -ne $temp.MetaData) { $script:Environment.EnvironmentInfo = ObjToShallowhashtable -object $Temp.Metadata } } end { } } # .\public\New-SimpleEnvServer.ps1 function New-SimpleEnvServer { <# .SYNOPSIS Creates a new SimpleEnvServer object. .PARAMETER Name Friendly name for the server .PARAMETER ComputerName The Network addressable name for the computer. This was changed from DnsName to provide better interoperability with built-in commands. .PARAMETER Environment A short environment identifier. .PARAMETER Tags A list of strings to tag the server with. .PARAMETER Roles A list of strings identifing the servers roles. .PARAMETER Properties A hashtable of properties / metadata to store about the server. This hashtable should be no more than 2 layers deep, or it may not be fully serialized. .Example PS> New-SimpleEnvServer -Name "Test01" Server DNS Name Environment Roles Tags Properties ------ -------- ----------- ----- ---- ---------- Test01 {} {} {} #> [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'low')] [OutputType([SimpleEnvServer])] param ( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [string] $Name, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [string] $Environment, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [Alias('FullName')] [Alias('DnsName')] [string] $ComputerName, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [string[]] $Tags, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [string[]] $Roles, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [Alias('Metadata')] [hashtable] $Properties ) begin { $ParametersToImport = [SimpleEnvServer].DeclaredProperties.Name } process { $Item = @{ Name = $Name } $ParametersToImport | ForEach-Object { if ($PSBoundParameters.ContainsKey($_)) { $Item[$_] = $PSBoundParameters[$_] } } if ($PSCmdlet.ShouldProcess("Create new SimpleEnvServer object")) { [SimpleEnvServer]$item } } end { } } # .\public\Remove-SimpleEnvServer.ps1 function Remove-SimpleEnvServer { <# .synopsis Remove a SimpleEnvServer object from the loaded environment, and optionally save the changes back to the environment config. .parameter ServerObject The [SimpleEnvServer] Object to remove. .parameter Save Save changes back to the environment config file at the end of pipeline exectution. .example PS> Get-Server -Tag Agent | Remove-SimpleEnvServer -Save Removes all servers tagged 'Agent' and saves the changes. #> [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'low')] param ( # # inputobject [Parameter(Mandatory = $true, ValueFromPipeline = $true)] # [ValidateScript( { $_ -is [SimpleEnvServer] })] [object] $ServerObject, # [Parameter(Mandatory = $false)] [switch] $Save ) process { $Server = [SimpleEnvServer]$ServerObject if ($PSCmdlet.ShouldProcess($Server.Name, "Remove from existing SimpleEnv ?")) { $script:Environment.Servers = $script:Environment.Servers | Where-Object { $_ -ne $Server } } } end { if ($Save.IsPresent -and $PSCmdlet.ShouldProcess( "Save changes to the existing environment?") ) { $SaveArgs = @{ Verbose = $Verbose } Save-SimpleEnv @SaveArgs } } } # .\public\Save-SimpleEnv.ps1 function Save-SimpleEnv { <# .Description Exports the current SimpleEnv configuration to the current Configuration File Path .Example PS> Save-SimpleEnv #> [CmdletBinding()] $ExportArgs = @{ FilePath = $Script:Configuration.ConfigFilePath Verbose = $VerbosePreference Force = $true } Export-SimpleEnv @ExportArgs } # .\public\Set-SimpleEnvConfiguration.ps1 function Set-SimpleEnvConfiguration { <# .SYNOPSIS Set SimpleEnv Configuration options. .PARAMETER FilePath Sets the path of the backing JSON File, and attempts to import it if it exists. If you want to overwrite the file without importing it, try Export-SimpleEnv instead. .EXAMPLE PS> Set-SimpleEnvConfiguration -FilePath 'myEnv.SimpleEnv.JSON' Imports the environment from myEnv.SimpleEnv.JSON, and will persist changes back to it. .LINK Export-SimpleEnv #> [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'low')] param ( # [Parameter(Mandatory = $true)] [string] $FilePath ) if ($PSCmdlet.ShouldProcess($Filepath, "Set the source environment JSON file to:" )) { try { Write-Verbose "Importing Configuration from $Filepath" if (Test-Path $Filepath) { Import-SimpleEnv -Filepath $Filepath } $Script:Configuration.ConfigFilePath = $Filepath } catch { Write-Error "Unable to import $Filepath" } } } # .\Post-Module.ps1 if (Test-Path -Path $Script:Configuration.ConfigFilePath) { Import-SimpleEnv -Filepath $Script:Configuration.ConfigFilePath } |