From 997ed564c801130a0a2dba7534e0e94fe659dd39 Mon Sep 17 00:00:00 2001 From: Nate Ferrell Date: Wed, 28 Aug 2019 14:51:33 -0500 Subject: [PATCH 01/13] updated Classes, module version, Copy-Parameters, and Get-PathAlias --- PSProfile/Classes/PSProfile.Classes.ps1 | 134 ++++++++++++------- PSProfile/PSProfile.psd1 | 2 +- PSProfile/Public/Helpers/Copy-Parameters.ps1 | 1 + PSProfile/Public/Helpers/Get-PathAlias.ps1 | 23 +++- 4 files changed, 105 insertions(+), 55 deletions(-) diff --git a/PSProfile/Classes/PSProfile.Classes.ps1 b/PSProfile/Classes/PSProfile.Classes.ps1 index 2363934..eb9a462 100644 --- a/PSProfile/Classes/PSProfile.Classes.ps1 +++ b/PSProfile/Classes/PSProfile.Classes.ps1 @@ -119,49 +119,7 @@ class PSProfile { $this.GitPathMap = @{ } $this.PSBuildPathMap = @{ } $this.SymbolicLinks = @{ } - $this.Prompts = @{ - Default = '"PS $($executionContext.SessionState.Path.CurrentLocation)$(">" * ($nestedPromptLevel + 1)) "; - # .Link - # https://go.microsoft.com/fwlink/?LinkID=225750 - # .ExternalHelp System.Management.Automation.dll-help.xml' - SCRTHQ = '$lastStatus = $? - $lastColor = if ($lastStatus -eq $true) { - "Green" - } - else { - "Red" - } - Write-Host "[" -NoNewline - Write-Host -ForegroundColor Cyan "#$($MyInvocation.HistoryId)" -NoNewline - Write-Host "] " -NoNewline - Write-Host "[" -NoNewLine - $verColor = @{ - ForegroundColor = if ($PSVersionTable.PSVersion.Major -eq 7) { - "Yellow" - } - elseif ($PSVersionTable.PSVersion.Major -eq 6) { - "Magenta" - } - else { - "Cyan" - } - } - Write-Host @verColor ("PS {0}" -f (Get-PSVersion)) -NoNewline - Write-Host "] " -NoNewline - Write-Host "[" -NoNewline - Write-Host -ForegroundColor $lastColor ("{0}" -f (Get-LastCommandDuration)) -NoNewline - Write-Host "] [" -NoNewline - Write-Host ("{0}" -f $(Get-PathAlias)) -NoNewline -ForegroundColor DarkYellow - Write-Host "]" -NoNewline - if ($PWD.Path -notlike "\\*" -and $env:DisablePoshGit -ne $true -and (Test-IfGit)) { - Write-VcsStatus - $GitPromptSettings.EnableWindowTitle = "PS {0} @" -f (Get-PSVersion) - } - else { - $Host.UI.RawUI.WindowTitle = "PS {0}" -f (Get-PSVersion) - } - "`n>> "' - } + $this.Prompts = @{ } $this.Variables = @{ Environment = @{ Home = [System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::UserProfile) @@ -174,9 +132,22 @@ class PSProfile { } } $this.Settings = @{ - DefaultPrompt = $null - PSVersionStringLength = 3 - ConfigurationPath = (Join-Path (Get-ConfigurationPath -CompanyName 'SCRT HQ' -Name PSProfile) 'Configuration.psd1') + DefaultPrompt = $null + PSVersionStringLength = 3 + ConfigurationPath = (Join-Path (Get-ConfigurationPath -CompanyName 'SCRT HQ' -Name PSProfile) 'Configuration.psd1') + FontType = 'Default' + PromptCharacters = @{ + GitRepo = @{ + NerdFonts = "$([char]0xf418)" + PowerLine = "$([char]0xe0a0)" + Default = "@" + } + AWS = @{ + NerdFonts = "$([char]0xf270)" + PowerLine = "AWS: " + Default = "AWS: " + } + } } $this.RefreshFrequency = (New-TimeSpan -Hours 1).ToString() $this.LastRefresh = [datetime]::Now.AddHours(-2) @@ -197,6 +168,73 @@ class PSProfile { "Debug" ) $this._loadConfiguration() + $this.Prompts['SCRTHQ'] = '$lastStatus = $? +$lastColor = if ($lastStatus -eq $true) { + "Green" +} +else { + "Red" +} +$isAdmin = $false +$isDesktop = ($PSVersionTable.PSVersion.Major -eq 5) +if ($isDesktop -or $IsWindows) { + $windowsIdentity = [System.Security.Principal.WindowsIdentity]::GetCurrent() + $windowsPrincipal = New-Object "System.Security.Principal.WindowsPrincipal" $windowsIdentity + $isAdmin = $windowsPrincipal.IsInRole("Administrators") -eq 1 +} else { + $isAdmin = ((& id -u) -eq 0) +} +if ($isAdmin) { + $idColor = "Magenta" +} +else { + $idColor = "Cyan" +} +Write-Host "[" -NoNewline +Write-Host -ForegroundColor $idColor "#$($MyInvocation.HistoryId)" -NoNewline +Write-Host "] [" -NoNewline +$verColor = @{ + ForegroundColor = if ($PSVersionTable.PSVersion.Major -eq 7) { + "Yellow" + } + elseif ($PSVersionTable.PSVersion.Major -eq 6) { + "Magenta" + } + else { + "Cyan" + } +} +Write-Host @verColor ("PS {0}" -f (Get-PSVersion)) -NoNewline +Write-Host "] [" -NoNewline +Write-Host -ForegroundColor $lastColor ("{0}" -f (Get-LastCommandDuration)) -NoNewline +Write-Host "] [" -NoNewline +Write-Host ("{0}" -f $(Get-PathAlias)) -NoNewline -ForegroundColor DarkYellow +if ((Get-Location -Stack).Count -gt 0) { + Write-Host (("+" * ((Get-Location -Stack).Count))) -NoNewLine -ForegroundColor Cyan +} +Write-Host "]" -NoNewline +if ($PWD.Path -notlike "\\*" -and $env:DisablePoshGit -ne $true) { + Write-VcsStatus + $GitPromptSettings.EnableWindowTitle = "PS {0} @" -f (Get-PSVersion) +} +else { + $Host.UI.RawUI.WindowTitle = "PS {0}" -f (Get-PSVersion) +} +if ($env:AWS_PROFILE) { + Write-Host "`n" -NoNewline + $awsIcon = if ($global:PSProfile.Settings.ContainsKey("FontType")) { + $global:PSProfile.Settings.PromptCharacters.AWS[$global:PSProfile.Settings.FontType] + } + else { + "AWS:" + } + if ([String]::IsNullOrEmpty($awsIcon)) { + $awsIcon = "AWS:" + } + Write-Host -ForegroundColor Black -BackgroundColor Yellow "$($awsIcon) $($env:AWS_PROFILE)" -NoNewline + Write-Host " " -NoNewline +} +"`n>> "' $plugPaths = @() $curVer = (Import-Metadata (Join-Path $PSScriptRoot "PSProfile.psd1")).ModuleVersion $this.PluginPaths | Where-Object { $_ -match "[\/\\](Modules|BuildOutput)[\/\\]PSProfile[\/\\]$curVer" -or $_ -notmatch "[\/\\](Modules|BuildOutput)[\/\\]PSProfile[\/\\]\d+\.\d+\.\d+" } | ForEach-Object { @@ -642,7 +680,7 @@ class PSProfile { 'Debug' ) if (-not [string]::IsNullOrEmpty((-join $this.ModulesToInstall))) { - $null = $this.ModulesToInstall | Where-Object {-not [string]::IsNullOrEmpty($_)} | Start-RSJob -Name { "_PSProfile_InstallModule_$($_)" } -VariablesToImport this -ScriptBlock { + $null = $this.ModulesToInstall | Where-Object { -not [string]::IsNullOrEmpty($_) } | Start-RSJob -Name { "_PSProfile_InstallModule_$($_)" } -VariablesToImport this -ScriptBlock { Param ( [parameter()] [object] @@ -699,7 +737,7 @@ class PSProfile { 'Debug' ) if (-not [string]::IsNullOrEmpty((-join $this.ModulesToImport))) { - $this.ModulesToImport | Where-Object {-not [string]::IsNullOrEmpty($_)} | ForEach-Object { + $this.ModulesToImport | Where-Object { -not [string]::IsNullOrEmpty($_) } | ForEach-Object { try { $params = if ($_ -is [string]) { @{Name = $_ } diff --git a/PSProfile/PSProfile.psd1 b/PSProfile/PSProfile.psd1 index 665628d..ef4857d 100644 --- a/PSProfile/PSProfile.psd1 +++ b/PSProfile/PSProfile.psd1 @@ -12,7 +12,7 @@ RootModule = 'PSProfile.psm1' # Version number of this module. -ModuleVersion = '0.1.9' +ModuleVersion = '0.2.0' # Supported PSEditions CompatiblePSEditions = @('Desktop','Core') diff --git a/PSProfile/Public/Helpers/Copy-Parameters.ps1 b/PSProfile/Public/Helpers/Copy-Parameters.ps1 index 45a694c..d29731a 100644 --- a/PSProfile/Public/Helpers/Copy-Parameters.ps1 +++ b/PSProfile/Public/Helpers/Copy-Parameters.ps1 @@ -34,6 +34,7 @@ function Copy-Parameters { [String] $From, [Parameter()] + [Alias('ExcludeParameter')] [String[]] $Exclude = @() ) diff --git a/PSProfile/Public/Helpers/Get-PathAlias.ps1 b/PSProfile/Public/Helpers/Get-PathAlias.ps1 index a4dc88f..7a76858 100644 --- a/PSProfile/Public/Helpers/Get-PathAlias.ps1 +++ b/PSProfile/Public/Helpers/Get-PathAlias.ps1 @@ -23,11 +23,14 @@ function Get-PathAlias { [parameter(Position = 1)] [string] $DirectorySeparator = $(if ($null -ne $global:PathAliasDirectorySeparator) { - $global:PathAliasDirectorySeparator - } - else { - [System.IO.Path]::DirectorySeparatorChar - }) + $global:PathAliasDirectorySeparator + } + else { + [System.IO.Path]::DirectorySeparatorChar + }), + [parameter(Position = 2)] + [string] + $FontType = $global:PSProfile.Settings.FontType ) Begin { try { @@ -55,7 +58,15 @@ function Get-PathAlias { } } if ($gitRepo = Test-IfGit) { - $gitIcon = [char]0xe0a0 + $gitIcon = if ($global:PSProfile.Settings.ContainsKey('FontType')) { + $global:PSProfile.Settings.PromptCharacters.GitRepo[$global:PSProfile.Settings.FontType] + } + else { + '@' + } + if ([String]::IsNullOrEmpty($gitIcon)) { + $gitIcon = '@' + } $key = $gitIcon + $gitRepo.Repo if (-not $global:PSProfile._internal.PathAliasMap.ContainsKey($key)) { $global:PSProfile._internal.PathAliasMap[$key] = $gitRepo.TopLevel From 5d77591449c8f18da577e875305b77ce26ac940a Mon Sep 17 00:00:00 2001 From: Nate Ferrell Date: Wed, 28 Aug 2019 15:51:34 -0500 Subject: [PATCH 02/13] removed FontType parameter from Get-PathAlias --- PSProfile/Public/Helpers/Get-PathAlias.ps1 | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/PSProfile/Public/Helpers/Get-PathAlias.ps1 b/PSProfile/Public/Helpers/Get-PathAlias.ps1 index 7a76858..d06f7db 100644 --- a/PSProfile/Public/Helpers/Get-PathAlias.ps1 +++ b/PSProfile/Public/Helpers/Get-PathAlias.ps1 @@ -27,10 +27,7 @@ function Get-PathAlias { } else { [System.IO.Path]::DirectorySeparatorChar - }), - [parameter(Position = 2)] - [string] - $FontType = $global:PSProfile.Settings.FontType + }) ) Begin { try { From 93799a4b5fa2371f4574ddb5a68a67b42efc9d4f Mon Sep 17 00:00:00 2001 From: Nate Ferrell Date: Thu, 29 Aug 2019 01:16:33 -0500 Subject: [PATCH 03/13] added base for configuration helper --- PSProfile/Private/Show-Menu.ps1 | 32 +++++++++ .../Start-PSProfileConfigurationHelper.ps1 | 65 +++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 PSProfile/Private/Show-Menu.ps1 create mode 100644 PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 diff --git a/PSProfile/Private/Show-Menu.ps1 b/PSProfile/Private/Show-Menu.ps1 new file mode 100644 index 0000000..1132702 --- /dev/null +++ b/PSProfile/Private/Show-Menu.ps1 @@ -0,0 +1,32 @@ +function Show-Menu { + [cmdletbinding()] + Param( + [Parameter(Position = 0,Mandatory = $True,HelpMessage = "Enter your menu text")] + [ValidateNotNullOrEmpty()] + [string]$Menu, + [Parameter(Position = 1)] + [ValidateNotNullOrEmpty()] + [string]$Title = "My Menu", + [Alias("cls")] + [switch]$ClearScreen + ) + + #clear the screen if requested + if ($ClearScreen) { + Clear-Host + } + + #build the menu prompt + $menuPrompt = $title + #add a return + $menuprompt += "`n" + #add an underline + $menuprompt += "-" * $title.Length + #add another return + $menuprompt += "`n" + #add the menu + $menuPrompt += $menu + + Read-Host -Prompt $menuprompt + +} diff --git a/PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 b/PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 new file mode 100644 index 0000000..b25ad84 --- /dev/null +++ b/PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 @@ -0,0 +1,65 @@ +function Start-PSProfileConfigurationHelper { + [CmdletBinding()] + Param () + Begin { + Write-Verbose "Starting PSProfile Configuration Helper..." + $private:color = @{ + Tip = "Green" + Command = "Cyan" + Warning = "Yellow" + Current = "Magenta" + } + $private:header = { + param([string]$title) + @( + "----------------------------------" + "| $($title.ToUpper())" + "----------------------------------" + ) -join "`n" + } + $private:choices = [System.Collections.Generic.List[string]]::new() + $private:tip = { + param([string]$text) + "TIP: $text" | Write-Host -ForegroundColor $private:color['Tip'] + } + $private:command = { + param([string]$text) + "COMMAND: $text" | Write-Host -ForegroundColor $private:color['Command'] + } + $private:warning = { + param([string]$text) + "WARNING: $text" | Write-Host -ForegroundColor $private:color['Warning'] + } + $private:current = { + param([string]$text) + "CURRENT: $text" | Write-Host -ForegroundColor $private:color['Current'] + } + $private:multi = { + .$private:tip("This accepts multiple answers as comma-separated values, e.g. 1,2,5") + } + } + Process { + @( + "" + "Welcome to PSProfile! This Configuration Helper serves as a way to jump-start" + "your PSProfile configuration and increase your workflow productivity quickly." + "" + "You'll be asked a few questions to help with setting up your PSProfile," + "including being provided information around performing the same configuration" + "tasks using the included functions after your initial setup is complete." + "" + "If you have any questions, comments or find any bugs, please open an issue" + "on the PSProfile repo: https://github.com/scrthq/PSProfile/issues/new" + ) | Write-Host + $private:legend = { + "" | Write-Host + .$private:header("Legend") | Write-Host + .$private:tip("$($private:color['Tip']) - Helpful tips and tricks") + .$private:command("$($private:color['Command']) - Commands to run to replicate the configuration update made") + .$private:warning("$($private:color['Warning']) - Any warnings to be aware of") + .$private:current("$($private:color['Current']) - Any existing configuration values for this section") + "" | Write-Host + } + .$private:legend + } +} From d25c21c3ddf42571e72cd5d99af9def97096f0d8 Mon Sep 17 00:00:00 2001 From: Nate Ferrell Date: Fri, 30 Aug 2019 22:11:47 -0500 Subject: [PATCH 04/13] more updates --- PSProfile/Plugins/PSProfile.PowerTools.ps1 | 14 ++- PSProfile/Private/Show-Menu.ps1 | 54 ++++++------ .../Start-PSProfileConfigurationHelper.ps1 | 85 ++++++++++++++----- 3 files changed, 100 insertions(+), 53 deletions(-) diff --git a/PSProfile/Plugins/PSProfile.PowerTools.ps1 b/PSProfile/Plugins/PSProfile.PowerTools.ps1 index 1b681d2..53b9ac8 100644 --- a/PSProfile/Plugins/PSProfile.PowerTools.ps1 +++ b/PSProfile/Plugins/PSProfile.PowerTools.ps1 @@ -689,8 +689,10 @@ function Start-BuildScript { .PARAMETER Project The path of the project to build. Allows tab-completion of PSBuildPath aliases if ProjectPaths are filled out with PSProfile that expand to the full path when invoked. + You can also pass the path to a folder containing a build.ps1 script, or a full path to another script entirely. + .PARAMETER Task - The list of Tasks to specify to the build.ps1 script. + The list of Tasks to specify to the Build script. .PARAMETER Engine The engine to open the clean environment with between powershell, pwsh, and pwsh-preview. Defaults to the current engine the clean environment is opened from. @@ -728,11 +730,7 @@ function Start-BuildScript { [parameter()] [Alias('ne','noe')] [Switch] - $NoExit, - [parameter()] - [Alias('nr','nor')] - [Switch] - $NoRestore + $NoExit ) DynamicParam { $bldFolder = if ([String]::IsNullOrEmpty($PSBoundParameters['Project']) -or $PSBoundParameters['Project'] -eq '.') { @@ -750,7 +748,7 @@ function Start-BuildScript { else { Join-Path $bldFolder "build.ps1" } - Copy-Parameters -From $bldFile -Exclude Project,Task,Engine,NoExit,NoRestore + Copy-Parameters -From $bldFile -Exclude Project,Task,Engine,NoExit } Process { if (-not $PSBoundParameters.ContainsKey('Project')) { @@ -787,7 +785,7 @@ function Start-BuildScript { $command += "```$false;" } $command += "Set-Location '$parent'; . .\build.ps1" - $PSBoundParameters.Keys | Where-Object {$_ -notin @('Project','Engine','NoExit','NoRestore','Debug','ErrorAction','ErrorVariable','InformationAction','InformationVariable','OutBuffer','OutVariable','PipelineVariable','WarningAction','WarningVariable','Verbose','Confirm','WhatIf')} | ForEach-Object { + $PSBoundParameters.Keys | Where-Object {$_ -notin @('Project','Engine','NoExit','Debug','ErrorAction','ErrorVariable','InformationAction','InformationVariable','OutBuffer','OutVariable','PipelineVariable','WarningAction','WarningVariable','Verbose','Confirm','WhatIf')} | ForEach-Object { if ($PSBoundParameters[$_].ToString() -in @('True','False')) { $command += " -$($_):```$$($PSBoundParameters[$_].ToString())" } diff --git a/PSProfile/Private/Show-Menu.ps1 b/PSProfile/Private/Show-Menu.ps1 index 1132702..794f6bc 100644 --- a/PSProfile/Private/Show-Menu.ps1 +++ b/PSProfile/Private/Show-Menu.ps1 @@ -1,32 +1,36 @@ function Show-Menu { [cmdletbinding()] Param( - [Parameter(Position = 0,Mandatory = $True,HelpMessage = "Enter your menu text")] - [ValidateNotNullOrEmpty()] - [string]$Menu, - [Parameter(Position = 1)] - [ValidateNotNullOrEmpty()] - [string]$Title = "My Menu", - [Alias("cls")] - [switch]$ClearScreen + [Parameter(Mandatory,Position = 0)] + [string] + $Title, + [Parameter(Mandatory,Position = 1)] + [string] + $Menu, + [Parameter(Position = 2)] + [string] + $Prompt = "Please choose the desired option(s)", + [Parameter()] + [System.ConsoleColor] + $TitleColor = $Host.UI.RawUI.ForegroundColor, + [Parameter()] + [string] + $Header, + [Parameter()] + [System.ConsoleColor] + $HeaderColor = $Host.UI.RawUI.ForegroundColor, + [Parameter()] + [switch] + $Clear ) - - #clear the screen if requested - if ($ClearScreen) { + if ($Clear) { Clear-Host + $script:HostHeader = $true } - - #build the menu prompt - $menuPrompt = $title - #add a return - $menuprompt += "`n" - #add an underline - $menuprompt += "-" * $title.Length - #add another return - $menuprompt += "`n" - #add the menu - $menuPrompt += $menu - - Read-Host -Prompt $menuprompt - + if ($Header) { + Write-Host -ForegroundColor $HeaderColor $Header + } + Write-Host -ForegroundColor $TitleColor "$title`n$("-" * $title.Length)`n" + Write-Host "$($Menu.Trim())`n" + Read-Host -Prompt $Prompt } diff --git a/PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 b/PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 index b25ad84..1b4cdaa 100644 --- a/PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 +++ b/PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 @@ -3,13 +3,13 @@ function Start-PSProfileConfigurationHelper { Param () Begin { Write-Verbose "Starting PSProfile Configuration Helper..." - $private:color = @{ + $_color = @{ Tip = "Green" Command = "Cyan" Warning = "Yellow" Current = "Magenta" } - $private:header = { + $_header = { param([string]$title) @( "----------------------------------" @@ -17,25 +17,25 @@ function Start-PSProfileConfigurationHelper { "----------------------------------" ) -join "`n" } - $private:choices = [System.Collections.Generic.List[string]]::new() - $private:tip = { + $_changes = [System.Collections.Generic.List[string]]::new() + $_tip = { param([string]$text) - "TIP: $text" | Write-Host -ForegroundColor $private:color['Tip'] + "TIP: $text" | Write-Host -ForegroundColor $_color['Tip'] } - $private:command = { + $_command = { param([string]$text) - "COMMAND: $text" | Write-Host -ForegroundColor $private:color['Command'] + "COMMAND: $text" | Write-Host -ForegroundColor $_color['Command'] } - $private:warning = { + $_warning = { param([string]$text) - "WARNING: $text" | Write-Host -ForegroundColor $private:color['Warning'] + "WARNING: $text" | Write-Host -ForegroundColor $_color['Warning'] } - $private:current = { + $_current = { param([string]$text) - "CURRENT: $text" | Write-Host -ForegroundColor $private:color['Current'] + "CURRENT: $text" | Write-Host -ForegroundColor $_color['Current'] } - $private:multi = { - .$private:tip("This accepts multiple answers as comma-separated values, e.g. 1,2,5") + $_multi = { + .$_tip("This accepts multiple answers as comma-separated values, e.g. 1,2,5") } } Process { @@ -51,15 +51,60 @@ function Start-PSProfileConfigurationHelper { "If you have any questions, comments or find any bugs, please open an issue" "on the PSProfile repo: https://github.com/scrthq/PSProfile/issues/new" ) | Write-Host - $private:legend = { + $_legend = { "" | Write-Host - .$private:header("Legend") | Write-Host - .$private:tip("$($private:color['Tip']) - Helpful tips and tricks") - .$private:command("$($private:color['Command']) - Commands to run to replicate the configuration update made") - .$private:warning("$($private:color['Warning']) - Any warnings to be aware of") - .$private:current("$($private:color['Current']) - Any existing configuration values for this section") + .$_header("Legend") | Write-Host + .$_tip("$($_color['Tip']) - Helpful tips and tricks") + .$_command("$($_color['Command']) - Commands to run to replicate the configuration update made") + .$_warning("$($_color['Warning']) - Any warnings to be aware of") + .$_current("$($_color['Current']) - Any existing configuration values for this section") "" | Write-Host } - .$private:legend + .$_legend + + $_menu = { + "" | Write-Host + .$_header("Menu") | Write-Host + $_options = @( + "Choose a PSProfile concept below to learn more and optionally update" + "the configuration for it as well:" + "" + "1 - Command Aliases" + "2 - Modules to Import" + "3 - Modules to Install" + "4 - Path Aliases" + "5 - Plugins" + "6 - Project Paths" + "7 - Prompts" + "8 - Script Paths" + "9 - Secrets" + "10 - Symbolic Links" + "11 - Variables" + "" + "Addtional options:" + "12 - Configuration Functions" + "13 - Helper Functions" + "14 - Meta Functions" + "" + "* - All concepts" + "" + "X - Exit" + ) + $_options | Write-Host + .$_multi + "" | Write-Host + Read-Host -Prompt "Enter your choice(s)" + } + $_choices = .$_menu + "Concepts chosen:" | Write-Host + if ($_choices -match '\*') { + "* - All concepts" | Write-Host + } + else { + $_choices.Split(',').Trim() | Where-Object {-not [string]::IsNullOrEmpty($_.Trim())} | ForEach-Object { + $item = $_ + $_options | Select-String "^$item\s+\-\s" + } + } } } From 623d5aeddc87fe092b2beda98ad2b13ee42d8fc5 Mon Sep 17 00:00:00 2001 From: Nate Ferrell Date: Sat, 31 Aug 2019 00:19:25 -0500 Subject: [PATCH 05/13] updates --- CHANGELOG.md | 6 + PSProfile/Classes/PSProfile.Classes.ps1 | 6 +- .../Remove-PSProfileCommandAlias.ps1 | 22 ++- .../Start-PSProfileConfigurationHelper.ps1 | 180 +++++++++++++----- 4 files changed, 158 insertions(+), 56 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 932adc6..796cc87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ * [PSProfile - ChangeLog](#psprofile---changelog) + * [0.2.0 - 2019-09-01](#020---2019-09-01) * [0.1.9 - 2019-08-26](#019---2019-08-26) * [0.1.8 - 2019-08-26](#018---2019-08-26) * [0.1.7 - 2019-08-25](#017---2019-08-25) @@ -14,6 +15,11 @@ # PSProfile - ChangeLog +## 0.2.0 - 2019-09-01 + +* Added `Start-PSProfileConfigurationHelper`. +* Added support for multiple Aliases to be removed at once on `Remove-PSProfileCommandAlias`. + ## 0.1.9 - 2019-08-26 * Renamed `Copy-DynamicParameters` to `Copy-Parameters` for correctness and cleaned up approach for building the ParameterDictionary. diff --git a/PSProfile/Classes/PSProfile.Classes.ps1 b/PSProfile/Classes/PSProfile.Classes.ps1 index eb9a462..a59637c 100644 --- a/PSProfile/Classes/PSProfile.Classes.ps1 +++ b/PSProfile/Classes/PSProfile.Classes.ps1 @@ -221,7 +221,7 @@ else { $Host.UI.RawUI.WindowTitle = "PS {0}" -f (Get-PSVersion) } if ($env:AWS_PROFILE) { - Write-Host "`n" -NoNewline + Write-Host "`n[" -NoNewline $awsIcon = if ($global:PSProfile.Settings.ContainsKey("FontType")) { $global:PSProfile.Settings.PromptCharacters.AWS[$global:PSProfile.Settings.FontType] } @@ -231,8 +231,8 @@ if ($env:AWS_PROFILE) { if ([String]::IsNullOrEmpty($awsIcon)) { $awsIcon = "AWS:" } - Write-Host -ForegroundColor Black -BackgroundColor Yellow "$($awsIcon) $($env:AWS_PROFILE)" -NoNewline - Write-Host " " -NoNewline + Write-Host -ForegroundColor Yellow "$($awsIcon) $($env:AWS_PROFILE)" -NoNewline + Write-Host "]" -NoNewline } "`n>> "' $plugPaths = @() diff --git a/PSProfile/Public/Command Aliases/Remove-PSProfileCommandAlias.ps1 b/PSProfile/Public/Command Aliases/Remove-PSProfileCommandAlias.ps1 index 47b95d8..aba7c9a 100644 --- a/PSProfile/Public/Command Aliases/Remove-PSProfileCommandAlias.ps1 +++ b/PSProfile/Public/Command Aliases/Remove-PSProfileCommandAlias.ps1 @@ -23,7 +23,7 @@ function Remove-PSProfileCommandAlias { [CmdletBinding(SupportsShouldProcess,ConfirmImpact = "High")] Param ( [Parameter(Mandatory,Position = 0,ValueFromPipeline)] - [String] + [String[]] $Alias, [Parameter()] [Switch] @@ -33,17 +33,19 @@ function Remove-PSProfileCommandAlias { $Save ) Process { - if ($PSCmdlet.ShouldProcess("Removing '$Alias' from `$PSProfile.CommandAliases")) { - Write-Verbose "Removing '$Alias' from `$PSProfile.CommandAliases" - $Global:PSProfile.CommandAliases.Remove($Alias) - if ($Force -and $null -ne (Get-Alias "$Alias*")) { - Write-Verbose "Removing Alias: $Alias" - Remove-Item $LinkPath -Force - } - if ($Save) { - Save-PSProfile + foreach ($al in $Alias) { + if ($PSCmdlet.ShouldProcess("Removing '$al' from `$PSProfile.CommandAliases")) { + Write-Verbose "Removing '$al' from `$PSProfile.CommandAliases" + $Global:PSProfile.CommandAliases.Remove($al) + if ($Force -and $null -ne (Get-Alias "$al*")) { + Write-Verbose "Removing Alias: $al" + Remove-Alias -Name $al -Force + } } } + if ($Save) { + Save-PSProfile + } } } diff --git a/PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 b/PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 index 1b4cdaa..9cf1dc0 100644 --- a/PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 +++ b/PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 @@ -1,15 +1,25 @@ function Start-PSProfileConfigurationHelper { + <# + .SYNOPSIS + Starts the PSProfile Configuration Helper. + + .DESCRIPTION + Starts the PSProfile Configuration Helper. + + .EXAMPLE + Start-PSProfileConfigurationHelper + #> [CmdletBinding()] Param () Begin { Write-Verbose "Starting PSProfile Configuration Helper..." - $_color = @{ + $color = @{ Tip = "Green" Command = "Cyan" Warning = "Yellow" Current = "Magenta" } - $_header = { + $header = { param([string]$title) @( "----------------------------------" @@ -17,25 +27,25 @@ function Start-PSProfileConfigurationHelper { "----------------------------------" ) -join "`n" } - $_changes = [System.Collections.Generic.List[string]]::new() - $_tip = { + $changes = [System.Collections.Generic.List[string]]::new() + $tip = { param([string]$text) - "TIP: $text" | Write-Host -ForegroundColor $_color['Tip'] + "TIP: $text" | Write-Host -ForegroundColor $color['Tip'] } - $_command = { + $command = { param([string]$text) - "COMMAND: $text" | Write-Host -ForegroundColor $_color['Command'] + "COMMAND: $text" | Write-Host -ForegroundColor $color['Command'] } - $_warning = { + $warning = { param([string]$text) - "WARNING: $text" | Write-Host -ForegroundColor $_color['Warning'] + Write-Warning -Message $text } - $_current = { - param([string]$text) - "CURRENT: $text" | Write-Host -ForegroundColor $_color['Current'] + $current = { + param([string]$item) + "EXISTING : $item" | Write-Host -ForegroundColor $color['Current'] } - $_multi = { - .$_tip("This accepts multiple answers as comma-separated values, e.g. 1,2,5") + $multi = { + .$tip("This accepts multiple answers as comma-separated values, e.g. 1,2,5") } } Process { @@ -51,21 +61,21 @@ function Start-PSProfileConfigurationHelper { "If you have any questions, comments or find any bugs, please open an issue" "on the PSProfile repo: https://github.com/scrthq/PSProfile/issues/new" ) | Write-Host - $_legend = { + $legend = { "" | Write-Host - .$_header("Legend") | Write-Host - .$_tip("$($_color['Tip']) - Helpful tips and tricks") - .$_command("$($_color['Command']) - Commands to run to replicate the configuration update made") - .$_warning("$($_color['Warning']) - Any warnings to be aware of") - .$_current("$($_color['Current']) - Any existing configuration values for this section") + .$header("Legend") | Write-Host + .$tip("$($color['Tip']) - Helpful tips and tricks") + .$command("$($color['Command']) - Commands to run to replicate the configuration update made") + .$warning("$($color['Warning']) - Any warnings to be aware of") + .$current("$($color['Current']) - Any existing configuration values for this section") "" | Write-Host } - .$_legend + .$legend - $_menu = { + $menu = { "" | Write-Host - .$_header("Menu") | Write-Host - $_options = @( + .$header("Menu") | Write-Host + $options = @( "Choose a PSProfile concept below to learn more and optionally update" "the configuration for it as well:" "" @@ -73,37 +83,121 @@ function Start-PSProfileConfigurationHelper { "2 - Modules to Import" "3 - Modules to Install" "4 - Path Aliases" - "5 - Plugins" - "6 - Project Paths" - "7 - Prompts" - "8 - Script Paths" - "9 - Secrets" - "10 - Symbolic Links" - "11 - Variables" + "5 - Plugin Paths" + "6 - Plugins" + "7 - Project Paths" + "8 - Prompts" + "9 - Script Paths" + "10 - Secrets" + "11 - Symbolic Links" + "12 - Variables" "" "Addtional options:" - "12 - Configuration Functions" - "13 - Helper Functions" - "14 - Meta Functions" + "13 - Configuration" + "14 - Helpers" + "15 - Meta" "" "* - All concepts" "" "X - Exit" + "" ) - $_options | Write-Host - .$_multi + $options | Write-Host + .$multi "" | Write-Host Read-Host -Prompt "Enter your choice(s)" } - $_choices = .$_menu - "Concepts chosen:" | Write-Host - if ($_choices -match '\*') { - "* - All concepts" | Write-Host + $choices = .$menu + if ($choices -match "X") { + "`nExiting Configuration Helper!`n" | Write-Host -ForegroundColor Yellow + return } else { - $_choices.Split(',').Trim() | Where-Object {-not [string]::IsNullOrEmpty($_.Trim())} | ForEach-Object { - $item = $_ - $_options | Select-String "^$item\s+\-\s" + "Concepts chosen:" | Write-Host + if ($choices -match '\*') { + $options | Select-String "^\*\s+\-\s" | Write-Host + $resolved = @(1..15) + } + else { + $resolved = $choices.Split(',').Trim() | Where-Object {-not [string]::IsNullOrEmpty($_)} + $resolved | ForEach-Object { + $item = $_ + $options | Select-String "^$item\s+\-\s" | Write-Host + } + } + foreach ($choice in $resolved) { + "" | Write-Host + $topic = (($options | Select-String "^$choice\s+\-\s") -replace "^$choice\s+\-\s(.*$)",'$1').Trim() + .$header($topic) + $helpTopic = 'about_PSProfile_' + ($topic -replace ' ','_') + "Getting the HelpTopic for this concept: $helpTopic" | Write-Host + Get-Help $helpTopic -Category HelpFile + .$tip("To view this conceptual HelpTopic at any time, run the following command:") + .$command("Get-Help $helpTopic") + "" | Write-Host + switch ($choice) { + 1 { + if ($Global:PSProfile.CommandAliases.Keys.Count) { + .$current("`n$(([PSCustomObject]$Global:PSProfile.CommandAliases | Format-List | Out-String).Trim())") + } + Write-Host "Would you like to add a Command Alias to your PSProfile?" + $decision = Read-Host "[Y]es | [N]o" + do { + switch -Regex ($decision) { + "[Yy]" { + $item1 = Read-Host "Please enter the command you would like to add an alias for (ex: Test-Path)" + $item2 = Read-Host "Please enter the alias that you would like to set for the command (ex: tp)" + .$command("Add-PSProfileCommandAlias -Command '$item1' -Alias '$item2'") + Add-PSProfileCommandAlias -Command $item1 -Alias $item2 -Verbose + $changes.Add("Command Aliases:") + $changes.Add(" - Comman") + } + } + "`nWould you like to add another $topic to your PSProfile?" | Write-Host + $decision = Read-Host "[Y]es | [N]o" + } + until ($decision -notmatch "[Yy]") + } + 2 { + + } + 3 { + + } + 4 { + + } + 5 { + + } + 6 { + + } + 7 { + + } + 8 { + + } + 9 { + + } + 10 { + + } + 11 { + + } + 12 { + + } + 13 { + + } + 14 { + + } + } } } } From d252bd99d4fd2cb1b54d0d4a3d913d1dcae212c0 Mon Sep 17 00:00:00 2001 From: Nate Ferrell Date: Sat, 31 Aug 2019 02:07:30 -0500 Subject: [PATCH 06/13] saving current progress --- CHANGELOG.md | 2 + PSProfile/Plugins/PSProfile.PowerTools.ps1 | 36 ++--- .../Start-PSProfileConfigurationHelper.ps1 | 143 +++++++++++++++--- 3 files changed, 140 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 796cc87..e912371 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,8 @@ * Added `Start-PSProfileConfigurationHelper`. * Added support for multiple Aliases to be removed at once on `Remove-PSProfileCommandAlias`. +* Updated default `SCRTHQ` prompt that comes with the module. +* Added support for NerdFonts and PowerLine switches on the prompts to switch char sets depending on the FontType. ## 0.1.9 - 2019-08-26 diff --git a/PSProfile/Plugins/PSProfile.PowerTools.ps1 b/PSProfile/Plugins/PSProfile.PowerTools.ps1 index 53b9ac8..fc3b743 100644 --- a/PSProfile/Plugins/PSProfile.PowerTools.ps1 +++ b/PSProfile/Plugins/PSProfile.PowerTools.ps1 @@ -724,9 +724,18 @@ function Start-BuildScript { [String[]] $Task, [Parameter(Position = 2)] + [ValidateSet('powershell','pwsh','pwsh-preview')] [Alias('e')] [String] - $Engine, + $Engine = $(if ($PSVersionTable.PSVersion.ToString() -match 'preview') { + 'pwsh-preview' + } + elseif ($PSVersionTable.PSVersion.Major -ge 6) { + 'pwsh' + } + else { + 'powershell' + }), [parameter()] [Alias('ne','noe')] [Switch] @@ -754,21 +763,6 @@ function Start-BuildScript { if (-not $PSBoundParameters.ContainsKey('Project')) { $PSBoundParameters['Project'] = '.' } - if (-not $PSBoundParameters.ContainsKey('Engine')) { - $PSBoundParameters['Engine'] = switch ($PSVersionTable.PSVersion.Major) { - 5 { - 'powershell' - } - default { - if ($PSVersionTable.PSVersion.PreReleaseLabel) { - 'pwsh-preview' - } - else { - 'pwsh' - } - } - } - } $parent = switch ($PSBoundParameters['Project']) { '.' { $PWD.Path @@ -777,13 +771,7 @@ function Start-BuildScript { $global:PSProfile.PSBuildPathMap[$PSBoundParameters['Project']] } } - $command = "$($PSBoundParameters['Engine']) -NoProfile -C `"```$env:NoNugetRestore = " - if ($NoRestore) { - $command += "```$true;" - } - else { - $command += "```$false;" - } + $command = "$Engine -NoProfile -C `"" $command += "Set-Location '$parent'; . .\build.ps1" $PSBoundParameters.Keys | Where-Object {$_ -notin @('Project','Engine','NoExit','Debug','ErrorAction','ErrorVariable','InformationAction','InformationVariable','OutBuffer','OutVariable','PipelineVariable','WarningAction','WarningVariable','Verbose','Confirm','WhatIf')} | ForEach-Object { if ($PSBoundParameters[$_].ToString() -in @('True','False')) { @@ -798,7 +786,7 @@ function Start-BuildScript { Invoke-Expression $command if ($NoExit) { Push-Location $parent - Enter-CleanEnvironment -Engine $PSBoundParameters['Engine'] -ImportModule + Enter-CleanEnvironment -Engine $Engine -ImportModule Pop-Location } } diff --git a/PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 b/PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 index 9cf1dc0..ede7526 100644 --- a/PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 +++ b/PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 @@ -1,5 +1,5 @@ function Start-PSProfileConfigurationHelper { - <# +<# .SYNOPSIS Starts the PSProfile Configuration Helper. @@ -28,6 +28,7 @@ function Start-PSProfileConfigurationHelper { ) -join "`n" } $changes = [System.Collections.Generic.List[string]]::new() + $changeHash = @{} $tip = { param([string]$text) "TIP: $text" | Write-Host -ForegroundColor $color['Tip'] @@ -113,7 +114,7 @@ function Start-PSProfileConfigurationHelper { return } else { - "Concepts chosen:" | Write-Host + "`nConcepts chosen:" | Write-Host if ($choices -match '\*') { $options | Select-String "^\*\s+\-\s" | Write-Host $resolved = @(1..15) @@ -142,30 +143,135 @@ function Start-PSProfileConfigurationHelper { } Write-Host "Would you like to add a Command Alias to your PSProfile?" $decision = Read-Host "[Y]es | [N]o" - do { - switch -Regex ($decision) { - "[Yy]" { - $item1 = Read-Host "Please enter the command you would like to add an alias for (ex: Test-Path)" - $item2 = Read-Host "Please enter the alias that you would like to set for the command (ex: tp)" - .$command("Add-PSProfileCommandAlias -Command '$item1' -Alias '$item2'") - Add-PSProfileCommandAlias -Command $item1 -Alias $item2 -Verbose - $changes.Add("Command Aliases:") - $changes.Add(" - Comman") + if ($decision -match "[Yy]") { + do { + switch -Regex ($decision) { + "[Yy]" { + $item1 = Read-Host "Please enter the command you would like to add an alias for (ex: Test-Path)" + $item2 = Read-Host "Please enter the alias that you would like to set for the command (ex: tp)" + if ($null -eq (Get-PSProfileCommandAlias -Alias $item2)) { + if (-not $changeHash.ContainsKey('Command Aliases')) { + $changes.Add("Command Aliases:") + $changeHash['Command Aliases'] = @{} + } + .$command("Add-PSProfileCommandAlias -Command '$item1' -Alias '$item2'") + Add-PSProfileCommandAlias -Command $item1 -Alias $item2 -Verbose + $changes.Add(" - Command: $item1") + $changes.Add(" Alias: $item2") + $changeHash['Command Aliases'][$item1] = $item2 + } + else { + .$warning("Command Alias '$item2' already exists on your PSProfile configuration! If you would like to overwrite it, run the following command:") + .$command("Add-PSProfileCommandAlias -Command '$item1' -Alias '$item2' -Force") + } + } } + "`nWould you like to add another Command Alias to your PSProfile?" | Write-Host + $decision = Read-Host "[Y]es | [N]o" } - "`nWould you like to add another $topic to your PSProfile?" | Write-Host - $decision = Read-Host "[Y]es | [N]o" + until ($decision -notmatch "[Yy]") } - until ($decision -notmatch "[Yy]") } 2 { - + if ($Global:PSProfile.ModulesToImport.Count) { + .$current((($Global:PSProfile.ModulesToImport | ForEach-Object {if ($_ -is [hashtable]){$_.Name}else{$_}}) -join ", ")) + } + Write-Host "Would you like to add a Module to Import to your PSProfile?" + $decision = Read-Host "[Y]es | [N]o" + if ($decision -match "[Yy]") { + do { + switch -Regex ($decision) { + "[Yy]" { + $item1 = Read-Host "Please enter the name of the module you would like to import during PSProfile load" + if ($null -eq (Get-PSProfileModuleToImport -Name $item1)) { + if (-not $changeHash.ContainsKey('Modules to Import')) { + $changes.Add("Modules to Import:") + $changeHash['Modules to Import'] = @() + } + .$command("Add-PSProfileModuleToImport -Name '$item1'") + Add-PSProfileModuleToImport -Name $item1 -Verbose + $changes.Add(" - Name: $item1") + $changeHash['Modules to Import'] += $item1 + } + else { + .$warning("Module to Import '$item1' already exists on your PSProfile configuration! If you would like to overwrite it, run the following command:") + .$command("Add-PSProfileModuleToImport -Name '$item1' -Force") + } + } + } + "`nWould you like to add another Module to Import to your PSProfile?" | Write-Host + $decision = Read-Host "[Y]es | [N]o" + } + until ($decision -notmatch "[Yy]") + } } 3 { - + if ($Global:PSProfile.ModulesToInstall.Count) { + .$current((($Global:PSProfile.ModulesToInstall | ForEach-Object {if ($_ -is [hashtable]){$_.Name}else{$_}}) -join ", ")) + } + Write-Host "Would you like to add a Module to Install to your PSProfile?" + $decision = Read-Host "[Y]es | [N]o" + if ($decision -match "[Yy]") { + do { + switch -Regex ($decision) { + "[Yy]" { + $item1 = Read-Host "Please enter the name of the module you would like to install via background job during PSProfile load" + if ($null -eq (Get-PSProfileModuleToInstall -Name $item1)) { + if (-not $changeHash.ContainsKey('Modules to Install')) { + $changes.Add("Modules to Install:") + $changeHash['Modules to Install'] = @() + } + .$command("Add-PSProfileModuleToInstall -Name '$item1'") + Add-PSProfileModuleToInstall -Name $item1 -Verbose + $changes.Add(" - Name: $item1") + $changeHash['Modules to Install'] += $item1 + } + else { + .$warning("Module to Install '$item1' already exists on your PSProfile configuration! If you would like to overwrite it, run the following command:") + .$command("Add-PSProfileModuleToInstall -Name '$item1' -Force") + } + } + } + "`nWould you like to add another Module to Install to your PSProfile?" | Write-Host + $decision = Read-Host "[Y]es | [N]o" + } + until ($decision -notmatch "[Yy]") + } } 4 { - + if ($Global:PSProfile.PathAliases.Keys.Count) { + .$current("`n$(([PSCustomObject]$Global:PSProfile.PathAliases | Format-List | Out-String).Trim())") + } + Write-Host "Would you like to add a Path Alias to your PSProfile?" + $decision = Read-Host "[Y]es | [N]o" + if ($decision -match "[Yy]") { + do { + switch -Regex ($decision) { + "[Yy]" { + $item1 = Read-Host "Please enter the path you would like to add an alias for (ex: C:\Users\$env:USERNAME)" + $item2 = Read-Host "Please enter the alias that you would like to set for the path (ex: ~)" + if ($null -eq (Get-PSProfilePathAlias -Alias $item2)) { + if (-not $changeHash.ContainsKey('Path Aliases')) { + $changes.Add("Path Aliases:") + $changeHash['Path Aliases'] = @{} + } + .$command("Add-PSProfilePathAlias -Path '$item1' -Alias '$item2'") + Add-PSProfilePathAlias -Path $item1 -Alias $item2 -Verbose + $changes.Add(" - Path: $item1") + $changes.Add(" Alias: $item2") + $changeHash['Path Aliases'][$item1] = $item2 + } + else { + .$warning("Path Alias '$item2' already exists on your PSProfile configuration! If you would like to overwrite it, run the following command:") + .$command("Add-PSProfilePathAlias -Path '$item1' -Alias '$item2' -Force") + } + } + } + "`nWould you like to add another Path Alias to your PSProfile?" | Write-Host + $decision = Read-Host "[Y]es | [N]o" + } + until ($decision -notmatch "[Yy]") + } } 5 { @@ -199,6 +305,9 @@ function Start-PSProfileConfigurationHelper { } } } + .$header("Changes made to configuration") + $changes | Write-Host + $changeHash } } } From 784fad6f5418c6e6849bb52cd8dc37b8b4efe4fc Mon Sep 17 00:00:00 2001 From: Nate Ferrell Date: Sat, 31 Aug 2019 16:23:59 -0500 Subject: [PATCH 07/13] saving work --- .gitconfig | 2 + .../Start-PSProfileConfigurationHelper.ps1 | 308 +++++++++++------- .../Public/Plugins/Add-PSProfilePlugin.ps1 | 3 +- 3 files changed, 190 insertions(+), 123 deletions(-) create mode 100644 .gitconfig diff --git a/.gitconfig b/.gitconfig new file mode 100644 index 0000000..2ffb8f5 --- /dev/null +++ b/.gitconfig @@ -0,0 +1,2 @@ +[alias] + syncup = !git remote set-url https://github.com/scrthq/PSProfile.git upstream && git fetch upstream && git checkout master && git merge upstream/master diff --git a/PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 b/PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 index ede7526..b358270 100644 --- a/PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 +++ b/PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 @@ -1,5 +1,5 @@ function Start-PSProfileConfigurationHelper { -<# + <# .SYNOPSIS Starts the PSProfile Configuration Helper. @@ -14,7 +14,7 @@ function Start-PSProfileConfigurationHelper { Begin { Write-Verbose "Starting PSProfile Configuration Helper..." $color = @{ - Tip = "Green" + Tip = "Green" Command = "Cyan" Warning = "Yellow" Current = "Magenta" @@ -28,7 +28,7 @@ function Start-PSProfileConfigurationHelper { ) -join "`n" } $changes = [System.Collections.Generic.List[string]]::new() - $changeHash = @{} + $changeHash = @{ } $tip = { param([string]$text) "TIP: $text" | Write-Host -ForegroundColor $color['Tip'] @@ -80,27 +80,26 @@ function Start-PSProfileConfigurationHelper { "Choose a PSProfile concept below to learn more and optionally update" "the configuration for it as well:" "" - "1 - Command Aliases" - "2 - Modules to Import" - "3 - Modules to Install" - "4 - Path Aliases" - "5 - Plugin Paths" - "6 - Plugins" - "7 - Project Paths" - "8 - Prompts" - "9 - Script Paths" - "10 - Secrets" - "11 - Symbolic Links" - "12 - Variables" + "[1] Command Aliases" + "[2] Modules to Import" + "[3] Modules to Install" + "[4] Path Aliases" + "[5] Plugin Paths" + "[6] Plugins" + "[7] Project Paths" + "[8] Prompts" + "[9] Script Paths" + "[10] Secrets" + "[11] Symbolic Links" + "[12] Variables" "" - "Addtional options:" - "13 - Configuration" - "14 - Helpers" - "15 - Meta" + "[13] Configuration" + "[14] Helpers" + "[15] Meta" "" - "* - All concepts" + "[*] All concepts" "" - "X - Exit" + "[X] Exit" "" ) $options | Write-Host @@ -109,26 +108,26 @@ function Start-PSProfileConfigurationHelper { Read-Host -Prompt "Enter your choice(s)" } $choices = .$menu - if ($choices -match "X") { + if ($choices -match "\[X\]") { "`nExiting Configuration Helper!`n" | Write-Host -ForegroundColor Yellow return } else { "`nConcepts chosen:" | Write-Host if ($choices -match '\*') { - $options | Select-String "^\*\s+\-\s" | Write-Host + $options | Select-String "^\[\*\]\s+" | Write-Host $resolved = @(1..15) } else { - $resolved = $choices.Split(',').Trim() | Where-Object {-not [string]::IsNullOrEmpty($_)} + $resolved = $choices.Split(',').Trim() | Where-Object { -not [string]::IsNullOrEmpty($_) } $resolved | ForEach-Object { $item = $_ - $options | Select-String "^$item\s+\-\s" | Write-Host + $options | Select-String "^\[$item\]\s+" | Write-Host } } foreach ($choice in $resolved) { "" | Write-Host - $topic = (($options | Select-String "^$choice\s+\-\s") -replace "^$choice\s+\-\s(.*$)",'$1').Trim() + $topic = (($options | Select-String "^\[$choice\]\s+") -replace "^\[$choice\]\s+(.*$)",'$1').Trim() .$header($topic) $helpTopic = 'about_PSProfile_' + ($topic -replace ' ','_') "Getting the HelpTopic for this concept: $helpTopic" | Write-Host @@ -142,139 +141,206 @@ function Start-PSProfileConfigurationHelper { .$current("`n$(([PSCustomObject]$Global:PSProfile.CommandAliases | Format-List | Out-String).Trim())") } Write-Host "Would you like to add a Command Alias to your PSProfile?" - $decision = Read-Host "[Y]es | [N]o" - if ($decision -match "[Yy]") { - do { - switch -Regex ($decision) { - "[Yy]" { - $item1 = Read-Host "Please enter the command you would like to add an alias for (ex: Test-Path)" - $item2 = Read-Host "Please enter the alias that you would like to set for the command (ex: tp)" - if ($null -eq (Get-PSProfileCommandAlias -Alias $item2)) { - if (-not $changeHash.ContainsKey('Command Aliases')) { - $changes.Add("Command Aliases:") - $changeHash['Command Aliases'] = @{} - } - .$command("Add-PSProfileCommandAlias -Command '$item1' -Alias '$item2'") - Add-PSProfileCommandAlias -Command $item1 -Alias $item2 -Verbose - $changes.Add(" - Command: $item1") - $changes.Add(" Alias: $item2") - $changeHash['Command Aliases'][$item1] = $item2 - } - else { - .$warning("Command Alias '$item2' already exists on your PSProfile configuration! If you would like to overwrite it, run the following command:") - .$command("Add-PSProfileCommandAlias -Command '$item1' -Alias '$item2' -Force") + $decision = Read-Host "[Y] Yes [N] No [X] Exit" + do { + switch -Regex ($decision) { + "[Yy]" { + $item1 = Read-Host "Please enter the command you would like to add an alias for (ex: Test-Path)" + $item2 = Read-Host "Please enter the alias that you would like to set for the command (ex: tp)" + if ($null -eq (Get-PSProfileCommandAlias -Alias $item2)) { + if (-not $changeHash.ContainsKey('Command Aliases')) { + $changes.Add("Command Aliases:") + $changeHash['Command Aliases'] = @{ } } + .$command("Add-PSProfileCommandAlias -Command '$item1' -Alias '$item2'") + Add-PSProfileCommandAlias -Command $item1 -Alias $item2 -Verbose + $changes.Add(" - Command: $item1") + $changes.Add(" Alias: $item2") + $changeHash['Command Aliases'][$item1] = $item2 } + else { + .$warning("Command Alias '$item2' already exists on your PSProfile configuration! If you would like to overwrite it, run the following command:") + .$command("Add-PSProfileCommandAlias -Command '$item1' -Alias '$item2' -Force") + } + "`nWould you like to add another Command Alias to your PSProfile?" | Write-Host + $decision = Read-Host "[Y] Yes [N] No [X] Exit" + } + "[Xx]" { + "`nExiting Configuration Helper!`n" | Write-Host -ForegroundColor Yellow + return } - "`nWould you like to add another Command Alias to your PSProfile?" | Write-Host - $decision = Read-Host "[Y]es | [N]o" } - until ($decision -notmatch "[Yy]") } + until ($decision -notmatch "[Yy]") } 2 { if ($Global:PSProfile.ModulesToImport.Count) { - .$current((($Global:PSProfile.ModulesToImport | ForEach-Object {if ($_ -is [hashtable]){$_.Name}else{$_}}) -join ", ")) - } - Write-Host "Would you like to add a Module to Import to your PSProfile?" - $decision = Read-Host "[Y]es | [N]o" - if ($decision -match "[Yy]") { - do { - switch -Regex ($decision) { - "[Yy]" { - $item1 = Read-Host "Please enter the name of the module you would like to import during PSProfile load" - if ($null -eq (Get-PSProfileModuleToImport -Name $item1)) { - if (-not $changeHash.ContainsKey('Modules to Import')) { - $changes.Add("Modules to Import:") - $changeHash['Modules to Import'] = @() + .$current( + ( + ( + $Global:PSProfile.ModulesToImport | ForEach-Object { + if ($_ -is [hashtable]) { + $_.Name + } + else { + $_ } - .$command("Add-PSProfileModuleToImport -Name '$item1'") - Add-PSProfileModuleToImport -Name $item1 -Verbose - $changes.Add(" - Name: $item1") - $changeHash['Modules to Import'] += $item1 } - else { - .$warning("Module to Import '$item1' already exists on your PSProfile configuration! If you would like to overwrite it, run the following command:") - .$command("Add-PSProfileModuleToImport -Name '$item1' -Force") + ) -join ", " + ) + ) + } + Write-Host "Would you like to add a Module to Import to your PSProfile?" + $decision = Read-Host "[Y] Yes [N] No [X] Exit" + do { + switch -Regex ($decision) { + "[Yy]" { + $item1 = Read-Host "Please enter the name of the module you would like to import during PSProfile load" + if ($null -eq (Get-PSProfileModuleToImport -Name $item1)) { + if (-not $changeHash.ContainsKey('Modules to Import')) { + $changes.Add("Modules to Import:") + $changeHash['Modules to Import'] = @() } + .$command("Add-PSProfileModuleToImport -Name '$item1'") + Add-PSProfileModuleToImport -Name $item1 -Verbose + $changes.Add(" - $item1") + $changeHash['Modules to Import'] += $item1 + } + else { + .$warning("Module to Import '$item1' already exists on your PSProfile configuration! If you would like to overwrite it, run the following command:") + .$command("Add-PSProfileModuleToImport -Name '$item1' -Force") } + "`nWould you like to add another Module to Import to your PSProfile?" | Write-Host + $decision = Read-Host "[Y] Yes [N] No [X] Exit" + } + "[Xx]" { + "`nExiting Configuration Helper!`n" | Write-Host -ForegroundColor Yellow + return } - "`nWould you like to add another Module to Import to your PSProfile?" | Write-Host - $decision = Read-Host "[Y]es | [N]o" } - until ($decision -notmatch "[Yy]") } + until ($decision -notmatch "[Yy]") } 3 { if ($Global:PSProfile.ModulesToInstall.Count) { - .$current((($Global:PSProfile.ModulesToInstall | ForEach-Object {if ($_ -is [hashtable]){$_.Name}else{$_}}) -join ", ")) - } - Write-Host "Would you like to add a Module to Install to your PSProfile?" - $decision = Read-Host "[Y]es | [N]o" - if ($decision -match "[Yy]") { - do { - switch -Regex ($decision) { - "[Yy]" { - $item1 = Read-Host "Please enter the name of the module you would like to install via background job during PSProfile load" - if ($null -eq (Get-PSProfileModuleToInstall -Name $item1)) { - if (-not $changeHash.ContainsKey('Modules to Install')) { - $changes.Add("Modules to Install:") - $changeHash['Modules to Install'] = @() + .$current( + ( + ( + $Global:PSProfile.ModulesToInstall | ForEach-Object { + if ($_ -is [hashtable]) { + $_.Name + } + else { + $_ } - .$command("Add-PSProfileModuleToInstall -Name '$item1'") - Add-PSProfileModuleToInstall -Name $item1 -Verbose - $changes.Add(" - Name: $item1") - $changeHash['Modules to Install'] += $item1 } - else { - .$warning("Module to Install '$item1' already exists on your PSProfile configuration! If you would like to overwrite it, run the following command:") - .$command("Add-PSProfileModuleToInstall -Name '$item1' -Force") + ) -join ", " + ) + ) + } + Write-Host "Would you like to add a Module to Install to your PSProfile?" + $decision = Read-Host "[Y] Yes [N] No [X] Exit" + do { + switch -Regex ($decision) { + "[Yy]" { + $item1 = Read-Host "Please enter the name of the module you would like to install via background job during PSProfile load" + if ($null -eq (Get-PSProfileModuleToInstall -Name $item1)) { + if (-not $changeHash.ContainsKey('Modules to Install')) { + $changes.Add("Modules to Install:") + $changeHash['Modules to Install'] = @() } + .$command("Add-PSProfileModuleToInstall -Name '$item1'") + Add-PSProfileModuleToInstall -Name $item1 -Verbose + $changes.Add(" - $item1") + $changeHash['Modules to Install'] += $item1 } + else { + .$warning("Module to Install '$item1' already exists on your PSProfile configuration! If you would like to overwrite it, run the following command:") + .$command("Add-PSProfileModuleToInstall -Name '$item1' -Force") + } + "`nWould you like to add another Module to Install to your PSProfile?" | Write-Host + $decision = Read-Host "[Y] Yes [N] No [X] Exit" + } + "[Xx]" { + "`nExiting Configuration Helper!`n" | Write-Host -ForegroundColor Yellow + return } - "`nWould you like to add another Module to Install to your PSProfile?" | Write-Host - $decision = Read-Host "[Y]es | [N]o" } - until ($decision -notmatch "[Yy]") } + until ($decision -notmatch "[Yy]") } 4 { if ($Global:PSProfile.PathAliases.Keys.Count) { .$current("`n$(([PSCustomObject]$Global:PSProfile.PathAliases | Format-List | Out-String).Trim())") } Write-Host "Would you like to add a Path Alias to your PSProfile?" - $decision = Read-Host "[Y]es | [N]o" - if ($decision -match "[Yy]") { - do { - switch -Regex ($decision) { - "[Yy]" { - $item1 = Read-Host "Please enter the path you would like to add an alias for (ex: C:\Users\$env:USERNAME)" - $item2 = Read-Host "Please enter the alias that you would like to set for the path (ex: ~)" - if ($null -eq (Get-PSProfilePathAlias -Alias $item2)) { - if (-not $changeHash.ContainsKey('Path Aliases')) { - $changes.Add("Path Aliases:") - $changeHash['Path Aliases'] = @{} - } - .$command("Add-PSProfilePathAlias -Path '$item1' -Alias '$item2'") - Add-PSProfilePathAlias -Path $item1 -Alias $item2 -Verbose - $changes.Add(" - Path: $item1") - $changes.Add(" Alias: $item2") - $changeHash['Path Aliases'][$item1] = $item2 - } - else { - .$warning("Path Alias '$item2' already exists on your PSProfile configuration! If you would like to overwrite it, run the following command:") - .$command("Add-PSProfilePathAlias -Path '$item1' -Alias '$item2' -Force") + $decision = Read-Host "[Y] Yes [N] No [X] Exit" + do { + switch -Regex ($decision) { + "[Yy]" { + $item1 = Read-Host "Please enter the path you would like to add an alias for (ex: C:\Users\$env:USERNAME)" + $item2 = Read-Host "Please enter the alias that you would like to set for the path (ex: ~)" + if ($null -eq (Get-PSProfilePathAlias -Alias $item2)) { + if (-not $changeHash.ContainsKey('Path Aliases')) { + $changes.Add("Path Aliases:") + $changeHash['Path Aliases'] = @{ } } + .$command("Add-PSProfilePathAlias -Path '$item1' -Alias '$item2'") + Add-PSProfilePathAlias -Path $item1 -Alias $item2 -Verbose + $changes.Add(" - Path: $item1") + $changes.Add(" Alias: $item2") + $changeHash['Path Aliases'][$item1] = $item2 } + else { + .$warning("Path Alias '$item2' already exists on your PSProfile configuration! If you would like to overwrite it, run the following command:") + .$command("Add-PSProfilePathAlias -Path '$item1' -Alias '$item2' -Force") + } + "`nWould you like to add another Path Alias to your PSProfile?" | Write-Host + $decision = Read-Host "[Y] Yes [N] No [X] Exit" + } + "[Xx]" { + "`nExiting Configuration Helper!`n" | Write-Host -ForegroundColor Yellow + return } - "`nWould you like to add another Path Alias to your PSProfile?" | Write-Host - $decision = Read-Host "[Y]es | [N]o" } - until ($decision -notmatch "[Yy]") } + until ($decision -notmatch "[Yy]") } 5 { - + if ($Global:PSProfile.PluginPaths.Count) { + .$current(($Global:PSProfile.PluginPaths -join ", ")) + } + Write-Host "Would you like to add an additional Plugin Path to your PSProfile?" + .$tip("This is only needed if you have PSProfile plugins in a path outside of your normal PSModulePath") + $decision = Read-Host "[Y] Yes [N] No [X] Exit" + do { + switch -Regex ($decision) { + "[Yy]" { + $item1 = Read-Host "Please enter the path to the additional plugin folder" + if ($null -eq (Get-PSProfilePluginPath -Name $item1)) { + if (-not $changeHash.ContainsKey('Plugin Paths')) { + $changes.Add("Plugin Paths:") + $changeHash['Plugin Paths'] = @() + } + .$command("Add-PSProfilePluginPath -Name '$item1'") + Add-PSProfilePluginPath -Name $item1 -Verbose + $changes.Add(" - $item1") + $changeHash['Plugin Paths'] += $item1 + } + else { + .$warning("Plugin Path '$item1' already exists on your PSProfile configuration! If you would like to overwrite it, run the following command:") + .$command("Add-PSProfilePluginPath -Name '$item1' -Force") + } + "`nWould you like to add another Plugin Path to your PSProfile?" | Write-Host + $decision = Read-Host "[Y] Yes [N] No [X] Exit" + } + "[Xx]" { + "`nExiting Configuration Helper!`n" | Write-Host -ForegroundColor Yellow + return + } + } + } + until ($decision -notmatch "[Yy]") } 6 { diff --git a/PSProfile/Public/Plugins/Add-PSProfilePlugin.ps1 b/PSProfile/Public/Plugins/Add-PSProfilePlugin.ps1 index 121de15..2baeceb 100644 --- a/PSProfile/Public/Plugins/Add-PSProfilePlugin.ps1 +++ b/PSProfile/Public/Plugins/Add-PSProfilePlugin.ps1 @@ -41,8 +41,7 @@ function Add-PSProfilePlugin { if ($PSBoundParameters.ContainsKey('ArgumentList')) { $plugin['ArgumentList'] = $ArgumentList } - $temp = $Global:PSProfile.Plugins | Where-Object {$_.Name -ne $pName} - $temp += $plugin + $temp = @(($Global:PSProfile.Plugins | Where-Object {$_.Name -ne $pName}),$plugin) $Global:PSProfile.Plugins = $temp } if ($Save) { From 825265ed1a6150dc06f684fbb990f08d113a171b Mon Sep 17 00:00:00 2001 From: Nate Ferrell Date: Sat, 31 Aug 2019 16:24:08 -0500 Subject: [PATCH 08/13] saving work --- .gitconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitconfig b/.gitconfig index 2ffb8f5..2fe14c4 100644 --- a/.gitconfig +++ b/.gitconfig @@ -1,2 +1,3 @@ [alias] - syncup = !git remote set-url https://github.com/scrthq/PSProfile.git upstream && git fetch upstream && git checkout master && git merge upstream/master + addup = !git remote add upstream https://github.com/scrthq/PSProfile.git + syncup = !git fetch upstream && git checkout master && git merge upstream/master From 80faf132e6d8eb9e85444322eb41722498a85a45 Mon Sep 17 00:00:00 2001 From: Nate Ferrell Date: Sun, 1 Sep 2019 03:15:19 -0500 Subject: [PATCH 09/13] SAVEPOINT --- CHANGELOG.md | 5 +- PSProfile/Classes/PSProfile.Classes.ps1 | 59 ++++++++++++++++--- PSProfile/Private/Show-Menu.ps1 | 36 ----------- .../Export-PSProfileConfiguration.ps1 | 20 +++++-- .../Start-PSProfileConfigurationHelper.ps1 | 13 +++- .../Add-PSProfileModuleToImport.ps1 | 32 ++++++---- .../Remove-PSProfileModuleToImport.ps1 | 14 +++-- .../Add-PSProfileModuleToInstall.ps1 | 32 ++++++---- .../Remove-PSProfileModuleToInstall.ps1 | 14 +++-- .../Public/Plugins/Add-PSProfilePlugin.ps1 | 6 +- 10 files changed, 141 insertions(+), 90 deletions(-) delete mode 100644 PSProfile/Private/Show-Menu.ps1 diff --git a/CHANGELOG.md b/CHANGELOG.md index e912371..000c3fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,10 +17,13 @@ ## 0.2.0 - 2019-09-01 -* Added `Start-PSProfileConfigurationHelper`. +* Added `Start-PSProfileConfigurationHelper` to provide a way * Added support for multiple Aliases to be removed at once on `Remove-PSProfileCommandAlias`. * Updated default `SCRTHQ` prompt that comes with the module. * Added support for NerdFonts and PowerLine switches on the prompts to switch char sets depending on the FontType. +* Added `IncludeVault` switch parameter to `Export-PSProfileConfiguration` to prevent exporting the Secrets Vault by default when creating portable configurations. +* Added `_cleanModules()` method to PSProfile class to remove any null or empty values hanging over and convert any string values to the full hashtable value instead. +* Added special module import process when the `ModuleToImport` is `EditorServicesCommandSuite` so it also automatically registers the available editor commands. ## 0.1.9 - 2019-08-26 diff --git a/PSProfile/Classes/PSProfile.Classes.ps1 b/PSProfile/Classes/PSProfile.Classes.ps1 index a59637c..5f82cad 100644 --- a/PSProfile/Classes/PSProfile.Classes.ps1 +++ b/PSProfile/Classes/PSProfile.Classes.ps1 @@ -144,7 +144,7 @@ class PSProfile { } AWS = @{ NerdFonts = "$([char]0xf270)" - PowerLine = "AWS: " + PowerLine = "$([char]0xf0e7)" Default = "AWS: " } } @@ -290,6 +290,7 @@ if ($env:AWS_PROFILE) { "MAIN", "Verbose" ) + $this._cleanModules() $this._findProjects() $this._installModules() $this._createSymbolicLinks() @@ -318,6 +319,33 @@ if ($env:AWS_PROFILE) { } return $content } + hidden [void] _cleanModules() { + $this._log( + "SECTION START", + "CleanModules", + "Debug" + ) + foreach ($section in @('ModulesToImport','ModulesToInstall')) { + [hashtable[]]$final = @() + $this.$section | Where-Object {$_ -is [hashtable] -and $_.Name} | ForEach-Object { + $final += $_ + } + $this.$section | Where-Object {$_ -is [string]} | ForEach-Object { + $this._log( + "[$section] Converting module string to hashtable: $_", + "CleanModules", + "Verbose" + ) + $final += @{Name = $_} + } + $this.$section = $final + } + $this._log( + "SECTION END", + "CleanModules", + "Debug" + ) + } hidden [void] _loadPrompt() { $this._log( "SECTION START", @@ -680,7 +708,7 @@ if ($env:AWS_PROFILE) { 'Debug' ) if (-not [string]::IsNullOrEmpty((-join $this.ModulesToInstall))) { - $null = $this.ModulesToInstall | Where-Object { -not [string]::IsNullOrEmpty($_) } | Start-RSJob -Name { "_PSProfile_InstallModule_$($_)" } -VariablesToImport this -ScriptBlock { + $null = $this.ModulesToInstall | Where-Object { ($_ -is [hashtable] -and $_.Name) -or ($_ -is [string] -and -not [string]::IsNullOrEmpty($_.Trim())) } | Start-RSJob -Name { "_PSProfile_InstallModule_$($_)" } -VariablesToImport this -ScriptBlock { Param ( [parameter()] [object] @@ -737,7 +765,7 @@ if ($env:AWS_PROFILE) { 'Debug' ) if (-not [string]::IsNullOrEmpty((-join $this.ModulesToImport))) { - $this.ModulesToImport | Where-Object { -not [string]::IsNullOrEmpty($_) } | ForEach-Object { + $this.ModulesToImport | Where-Object { ($_ -is [hashtable] -and $_.Name) -or ($_ -is [string] -and -not [string]::IsNullOrEmpty($_.Trim())) } | ForEach-Object { try { $params = if ($_ -is [string]) { @{Name = $_ } @@ -754,12 +782,25 @@ if ($env:AWS_PROFILE) { $params.Remove($_) } } - Import-Module @params -Global -ErrorAction SilentlyContinue -Verbose:$false - $this._log( - "Module imported: $($params | ConvertTo-Json -Compress)", - 'ImportModules', - 'Verbose' - ) + if ($params.Name -ne 'EditorServicesCommandSuite') { + Import-Module @params -Global -ErrorAction SilentlyContinue -Verbose:$false + $this._log( + "Module imported: $($params | ConvertTo-Json -Compress)", + 'ImportModules', + 'Verbose' + ) + } + elseif ($params.Name -eq 'EditorServicesCommandSuite' -and $psEditor) { + Import-Module EditorServicesCommandSuite -ErrorAction SilentlyContinue -Global -Force -Verbose:$false + # Twice because: https://github.com/SeeminglyScience/EditorServicesCommandSuite/issues/40 + Import-Module EditorServicesCommandSuite -ErrorAction SilentlyContinue -Global -Force -Verbose:$false + Import-EditorCommand -Module EditorServicesCommandSuite -Force -Verbose:$false + $this._log( + "Module imported: $($params | ConvertTo-Json -Compress)", + 'ImportModules', + 'Verbose' + ) + } } else { $this._log( diff --git a/PSProfile/Private/Show-Menu.ps1 b/PSProfile/Private/Show-Menu.ps1 deleted file mode 100644 index 794f6bc..0000000 --- a/PSProfile/Private/Show-Menu.ps1 +++ /dev/null @@ -1,36 +0,0 @@ -function Show-Menu { - [cmdletbinding()] - Param( - [Parameter(Mandatory,Position = 0)] - [string] - $Title, - [Parameter(Mandatory,Position = 1)] - [string] - $Menu, - [Parameter(Position = 2)] - [string] - $Prompt = "Please choose the desired option(s)", - [Parameter()] - [System.ConsoleColor] - $TitleColor = $Host.UI.RawUI.ForegroundColor, - [Parameter()] - [string] - $Header, - [Parameter()] - [System.ConsoleColor] - $HeaderColor = $Host.UI.RawUI.ForegroundColor, - [Parameter()] - [switch] - $Clear - ) - if ($Clear) { - Clear-Host - $script:HostHeader = $true - } - if ($Header) { - Write-Host -ForegroundColor $HeaderColor $Header - } - Write-Host -ForegroundColor $TitleColor "$title`n$("-" * $title.Length)`n" - Write-Host "$($Menu.Trim())`n" - Read-Host -Prompt $Prompt -} diff --git a/PSProfile/Public/Configuration/Export-PSProfileConfiguration.ps1 b/PSProfile/Public/Configuration/Export-PSProfileConfiguration.ps1 index 5048d61..6c10970 100644 --- a/PSProfile/Public/Configuration/Export-PSProfileConfiguration.ps1 +++ b/PSProfile/Public/Configuration/Export-PSProfileConfiguration.ps1 @@ -9,6 +9,9 @@ function Export-PSProfileConfiguration { .PARAMETER Path The existing folder or file path with PSD1 extension to export the configuration to. If a folder path is provided, the configuration will be exported to the path with the file name 'PSProfile.Configuration.psd1'. + .PARAMETER IncludeVault + If $true, includes the Vault property as well so Secrets are also exported. + .PARAMETER Force If $true and the resolved file path exists, overwrite it with the current configuration. @@ -20,10 +23,7 @@ function Export-PSProfileConfiguration { .EXAMPLE Export-PSProfileConfiguration ~\MyScripts -Force - Exports the configuration to the resolved path of '~\MyScripts\PSProfile.Configuration.psd1' and overwrites the file if it already exists. - - .NOTES - *Any secrets stored in the `$PSProfile.Vault` will be exported, but will be unable to be decrypted on another machine or by another user on the same machine due to encryption via Data Protection API.* + Exports the configuration to the resolved path of '~\MyScripts\PSProfile.Configuration.psd1' and overwrites the file if it already exists. The exported configuration does *not* include the Vault to prevent secrets from being migrated with the portable configuration that is exported. #> [CmdletBinding()] Param ( @@ -43,6 +43,9 @@ function Export-PSProfileConfiguration { $Path, [Parameter()] [Switch] + $IncludeVault, + [Parameter()] + [Switch] $Force ) Process { @@ -74,7 +77,14 @@ function Export-PSProfileConfiguration { } Write-Verbose "Importing metadata from path: $($Global:PSProfile.Settings.ConfigurationPath)" $metadata = Import-Metadata -Path $Global:PSProfile.Settings.ConfigurationPath -ErrorAction Stop - Write-Verbose "Exporting cleaned PSProfile configuration to path: $finalPath" + if (-not $IncludeVault -and $metadata.ContainsKey('Vault')) { + Write-Warning "Removing the Secrets Vault from the PSProfile configuration for safety. If you would like to export the configuration with the Vault included, use the -IncludeVault parameter with this function" + $metadata.Remove('Vault') | Out-Null + Write-Verbose "Exporting cleaned PSProfile configuration to path: $finalPath" + } + else { + Write-Verbose "Exporting PSProfile configuration to path: $finalPath" + } $metadata | Export-Metadata -Path $finalPath -ErrorAction Stop } catch { diff --git a/PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 b/PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 index b358270..be07763 100644 --- a/PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 +++ b/PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 @@ -108,7 +108,7 @@ function Start-PSProfileConfigurationHelper { Read-Host -Prompt "Enter your choice(s)" } $choices = .$menu - if ($choices -match "\[X\]") { + if ($choices -match "[Xx]") { "`nExiting Configuration Helper!`n" | Write-Host -ForegroundColor Yellow return } @@ -373,7 +373,16 @@ function Start-PSProfileConfigurationHelper { } .$header("Changes made to configuration") $changes | Write-Host - $changeHash + "" | Write-Host + "Would you like to save your PSProfile configuration?" | Write-Host + $decision = Read-Host "[Y] Yes [N] No [X] Exit" + switch -Regex ($decision) { + "[Yy]" { + Save-PSProfile -Verbose + } + } + "`nConfiguration Helper complete! Exiting`n" | Write-Host -ForegroundColor Yellow + return } } } diff --git a/PSProfile/Public/Modules to Import/Add-PSProfileModuleToImport.ps1 b/PSProfile/Public/Modules to Import/Add-PSProfileModuleToImport.ps1 index f961917..563231c 100644 --- a/PSProfile/Public/Modules to Import/Add-PSProfileModuleToImport.ps1 +++ b/PSProfile/Public/Modules to Import/Add-PSProfileModuleToImport.ps1 @@ -35,7 +35,7 @@ function Add-PSProfileModuleToImport { [CmdletBinding()] Param ( [Parameter(Mandatory,Position = 0,ValueFromPipeline)] - [String] + [String[]] $Name, [Parameter()] [String] @@ -57,18 +57,26 @@ function Add-PSProfileModuleToImport { $Save ) Process { - if (-not $Force -and $null -ne ($Global:PSProfile.ModulesToImport | Where-Object {$_.Name -eq $Name})) { - Write-Error "Unable to add module to `$PSProfile.ModulesToImport as it already exists. Use -Force to overwrite the existing value if desired." - } - else { - $moduleParams = $PSBoundParameters - foreach ($key in $moduleParams.Keys | Where-Object {$_ -in @('Verbose','Confirm','Force') -or $_ -notin (Get-Command Import-Module).Parameters.Keys}) { - $null = $moduleParams.Remove($key) + foreach ($mod in $Name) { + if (-not $Force -and $null -ne ($Global:PSProfile.ModulesToImport | Where-Object {$_.Name -eq $mod})) { + Write-Error "Unable to add module to `$PSProfile.ModulesToImport as it already exists. Use -Force to overwrite the existing value if desired." } - Write-Verbose "Adding '$Name' to `$PSProfile.ModulesToImport" - $Global:PSProfile.ModulesToImport = @($Global:PSProfile.ModulesToImport,$moduleParams) - if ($Save) { - Save-PSProfile + else { + $moduleParams = @{ + Name = $mod + } + $PSBoundParameters.GetEnumerator() | Where-Object {$_.Key -in @('Prefix','MinimumVersion','RequiredVersion','ArgumentList')} | ForEach-Object { + $moduleParams[$_.Key] = $_.Value + } + Write-Verbose "Adding '$mod' to `$PSProfile.ModulesToImport" + [hashtable[]]$final = @($moduleParams) + $Global:PSProfile.ModulesToImport | Where-Object {$_.Name -ne $mod} | ForEach-Object { + $final += $_ + } + $Global:PSProfile.ModulesToImport = $final + if ($Save) { + Save-PSProfile + } } } } diff --git a/PSProfile/Public/Modules to Import/Remove-PSProfileModuleToImport.ps1 b/PSProfile/Public/Modules to Import/Remove-PSProfileModuleToImport.ps1 index 1b9faf0..3abb0fa 100644 --- a/PSProfile/Public/Modules to Import/Remove-PSProfileModuleToImport.ps1 +++ b/PSProfile/Public/Modules to Import/Remove-PSProfileModuleToImport.ps1 @@ -20,18 +20,20 @@ function Remove-PSProfileModuleToImport { [CmdletBinding(SupportsShouldProcess,ConfirmImpact = "High")] Param ( [Parameter(Mandatory,Position = 0,ValueFromPipeline)] - [String] + [String[]] $Name, [Parameter()] [Switch] $Save ) Process { - if ($PSCmdlet.ShouldProcess("Removing '$Name' from `$PSProfile.ModulesToImport")) { - Write-Verbose "Removing '$Name' from `$PSProfile.ModulesToImport" - $Global:PSProfile.ModulesToImport = $Global:PSProfile.ModulesToImport | Where-Object {($_ -is [hashtable] -and $_.Name -ne $Name) -or ($_ -is [string] -and $_ -ne $Name)} - if ($Save) { - Save-PSProfile + foreach ($mod in $Name) { + if ($PSCmdlet.ShouldProcess("Removing '$mod' from `$PSProfile.ModulesToImport")) { + Write-Verbose "Removing '$mod' from `$PSProfile.ModulesToImport" + $Global:PSProfile.ModulesToImport = $Global:PSProfile.ModulesToImport | Where-Object {($_ -is [hashtable] -and $_.Name -ne $mod) -or ($_ -is [string] -and $_ -ne $mod)} + if ($Save) { + Save-PSProfile + } } } } diff --git a/PSProfile/Public/Modules to Install/Add-PSProfileModuleToInstall.ps1 b/PSProfile/Public/Modules to Install/Add-PSProfileModuleToInstall.ps1 index 5c9cea3..ad85b0b 100644 --- a/PSProfile/Public/Modules to Install/Add-PSProfileModuleToInstall.ps1 +++ b/PSProfile/Public/Modules to Install/Add-PSProfileModuleToInstall.ps1 @@ -38,7 +38,7 @@ function Add-PSProfileModuleToInstall { [CmdletBinding()] Param ( [Parameter(Mandatory,Position = 0,ValueFromPipeline)] - [String] + [String[]] $Name, [Parameter()] [String] @@ -63,18 +63,26 @@ function Add-PSProfileModuleToInstall { $Save ) Process { - if (-not $Force -and $null -ne ($Global:PSProfile.ModulesToInstall | Where-Object {$_.Name -eq $Name})) { - Write-Error "Unable to add module to `$PSProfile.ModulesToInstall as it already exists. Use -Force to overwrite the existing value if desired." - } - else { - $moduleParams = $PSBoundParameters - foreach ($key in $moduleParams.Keys | Where-Object {$_ -in @('Verbose','Confirm','Force') -or $_ -notin (Get-Command Install-Module).Parameters.Keys}) { - $moduleParams.Remove($key) + foreach ($mod in $Name) { + if (-not $Force -and $null -ne ($Global:PSProfile.ModulesToInstall | Where-Object {$_.Name -eq $mod})) { + Write-Error "Unable to add module '$mod' to `$PSProfile.ModulesToInstall as it already exists. Use -Force to overwrite the existing value if desired." } - Write-Verbose "Adding '$Name' to `$PSProfile.ModulesToInstall" - $Global:PSProfile.ModulesToInstall = @($Global:PSProfile.ModulesToInstall,$moduleParams) - if ($Save) { - Save-PSProfile + else { + $moduleParams = @{ + Name = $mod + } + $PSBoundParameters.GetEnumerator() | Where-Object {$_.Key -in @('Repository','MinimumVersion','RequiredVersion','AcceptLicense','AllowPrerelease','Force')} | ForEach-Object { + $moduleParams[$_.Key] = $_.Value + } + Write-Verbose "Adding '$mod' to `$PSProfile.ModulesToInstall" + [hashtable[]]$final = @($moduleParams) + $Global:PSProfile.ModulesToInstall | Where-Object {$_.Name -ne $mod} | ForEach-Object { + $final += $_ + } + $Global:PSProfile.ModulesToInstall = $final + if ($Save) { + Save-PSProfile + } } } } diff --git a/PSProfile/Public/Modules to Install/Remove-PSProfileModuleToInstall.ps1 b/PSProfile/Public/Modules to Install/Remove-PSProfileModuleToInstall.ps1 index 0715ac4..1768e41 100644 --- a/PSProfile/Public/Modules to Install/Remove-PSProfileModuleToInstall.ps1 +++ b/PSProfile/Public/Modules to Install/Remove-PSProfileModuleToInstall.ps1 @@ -20,18 +20,20 @@ function Remove-PSProfileModuleToInstall { [CmdletBinding(SupportsShouldProcess,ConfirmImpact = "High")] Param ( [Parameter(Mandatory,Position = 0,ValueFromPipeline)] - [String] + [String[]] $Name, [Parameter()] [Switch] $Save ) Process { - if ($PSCmdlet.ShouldProcess("Removing '$Name' from `$PSProfile.ModulesToInstall")) { - Write-Verbose "Removing '$Name' from `$PSProfile.ModulesToInstall" - $Global:PSProfile.ModulesToInstall = $Global:PSProfile.ModulesToInstall | Where-Object {($_ -is [hashtable] -and $_.Name -ne $Name) -or ($_ -is [string] -and $_ -ne $Name)} - if ($Save) { - Save-PSProfile + foreach ($mod in $Name) { + if ($PSCmdlet.ShouldProcess("Removing '$mod' from `$PSProfile.ModulesToInstall")) { + Write-Verbose "Removing '$mod' from `$PSProfile.ModulesToInstall" + $Global:PSProfile.ModulesToInstall = $Global:PSProfile.ModulesToInstall | Where-Object {($_ -is [hashtable] -and $_.Name -ne $mod) -or ($_ -is [string] -and $_ -ne $mod)} + if ($Save) { + Save-PSProfile + } } } } diff --git a/PSProfile/Public/Plugins/Add-PSProfilePlugin.ps1 b/PSProfile/Public/Plugins/Add-PSProfilePlugin.ps1 index 2baeceb..a534bfa 100644 --- a/PSProfile/Public/Plugins/Add-PSProfilePlugin.ps1 +++ b/PSProfile/Public/Plugins/Add-PSProfilePlugin.ps1 @@ -41,7 +41,11 @@ function Add-PSProfilePlugin { if ($PSBoundParameters.ContainsKey('ArgumentList')) { $plugin['ArgumentList'] = $ArgumentList } - $temp = @(($Global:PSProfile.Plugins | Where-Object {$_.Name -ne $pName}),$plugin) + $temp = @() + $Global:PSProfile.Plugins | Where-Object {$_.Name -ne $pName} | ForEach-Object { + $temp += $_ + } + $temp += $plugin $Global:PSProfile.Plugins = $temp } if ($Save) { From ed13f6b83a6d91f7441132e4ee734e4ebfcd491d Mon Sep 17 00:00:00 2001 From: Nate Ferrell Date: Mon, 2 Sep 2019 10:50:23 -0500 Subject: [PATCH 10/13] SAVEPOINT --- CHANGELOG.md | 6 ++++ .../Start-PSProfileConfigurationHelper.ps1 | 36 ++++++++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 000c3fb..5366401 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,12 @@ * Added `IncludeVault` switch parameter to `Export-PSProfileConfiguration` to prevent exporting the Secrets Vault by default when creating portable configurations. * Added `_cleanModules()` method to PSProfile class to remove any null or empty values hanging over and convert any string values to the full hashtable value instead. * Added special module import process when the `ModuleToImport` is `EditorServicesCommandSuite` so it also automatically registers the available editor commands. +* Cleaned up logic and fixed bugs in the following functions: + * `Add-PSProfileModuleToImport` + * `Remove-PSProfileModuleToImport` + * `Add-PSProfileModuleToInstall` + * `Remove-PSProfileModuleToInstall` + * `Add-PSProfilePlugin` ## 0.1.9 - 2019-08-26 diff --git a/PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 b/PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 index be07763..d093024 100644 --- a/PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 +++ b/PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 @@ -343,7 +343,41 @@ function Start-PSProfileConfigurationHelper { until ($decision -notmatch "[Yy]") } 6 { - + if ($Global:PSProfile.Plugins.Count) { + .$current(($Global:PSProfile.Plugins.Name -join ", ")) + } + Write-Host "Would you like to add a Plugin to your PSProfile?" + .$tip("Plugins can be either scripts or modules.)") + .$tip("Use AD cmdlets? Try adding the plugin 'PSProfile.ADCompleters' to get tab-completion for the Properties parameter on Get-ADUser, Get-ADGroup, and Get-ADComputer!") + $decision = Read-Host "[Y] Yes [N] No [X] Exit" + do { + switch -Regex ($decision) { + "[Yy]" { + $item1 = Read-Host "Please enter the name of the plugin you would like to add (ex: PSProfile.ADCompleters)" + if ($null -eq (Get-PSProfilePlugin -Name $item1)) { + if (-not $changeHash.ContainsKey('Plugins')) { + $changes.Add("Plugins:") + $changeHash['Plugins'] = @() + } + .$command("Add-PSProfilePlugin -Name '$item1'") + Add-PSProfilePlugin -Name $item1 -Verbose + $changes.Add(" - $item1") + $changeHash['Plugins'] += $item1 + } + else { + .$warning("Plugin '$item1' already exists on your PSProfile configuration! If you would like to overwrite it, run the following command:") + .$command("Add-PSProfilePlugin -Name '$item1' -Force") + } + "`nWould you like to add another Plugin to your PSProfile?" | Write-Host + $decision = Read-Host "[Y] Yes [N] No [X] Exit" + } + "[Xx]" { + "`nExiting Configuration Helper!`n" | Write-Host -ForegroundColor Yellow + return + } + } + } + until ($decision -notmatch "[Yy]") } 7 { From 82ad7a1c063056ae2d52db5b2ca1f048fda4953a Mon Sep 17 00:00:00 2001 From: Nate Ferrell Date: Mon, 2 Sep 2019 11:10:54 -0500 Subject: [PATCH 11/13] SAVEPOINT --- .../Start-PSProfileConfigurationHelper.ps1 | 34 ++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 b/PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 index d093024..ab5f082 100644 --- a/PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 +++ b/PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 @@ -380,7 +380,39 @@ function Start-PSProfileConfigurationHelper { until ($decision -notmatch "[Yy]") } 7 { - + if ($Global:PSProfile.ProjectPaths.Count) { + .$current(($Global:PSProfile.ProjectPaths -join ", ")) + } + Write-Host "Would you like to add an additional Project Path to your PSProfile?" + $decision = Read-Host "[Y] Yes [N] No [X] Exit" + do { + switch -Regex ($decision) { + "[Yy]" { + $item1 = Read-Host "Please enter the path to the additional project folder" + if ($null -eq (Get-PSProfileProjectPath -Name $item1)) { + if (-not $changeHash.ContainsKey('Project Paths')) { + $changes.Add("Project Paths:") + $changeHash['Project Paths'] = @() + } + .$command("Add-PSProfileProjectPath -Name '$item1'") + Add-PSProfileProjectPath -Name $item1 -Verbose + $changes.Add(" - $item1") + $changeHash['Project Paths'] += $item1 + } + else { + .$warning("Project Path '$item1' already exists on your PSProfile configuration! If you would like to overwrite it, run the following command:") + .$command("Add-PSProfileProjectPath -Name '$item1' -Force") + } + "`nWould you like to add another Project Path to your PSProfile?" | Write-Host + $decision = Read-Host "[Y] Yes [N] No [X] Exit" + } + "[Xx]" { + "`nExiting Configuration Helper!`n" | Write-Host -ForegroundColor Yellow + return + } + } + } + until ($decision -notmatch "[Yy]") } 8 { From 28f47e0be3ecf008787b90a9642760aacc31beeb Mon Sep 17 00:00:00 2001 From: Nate Ferrell Date: Mon, 2 Sep 2019 21:43:41 -0500 Subject: [PATCH 12/13] SAVEPOINT --- CHANGELOG.md | 38 +- CONTRIBUTING.md | 22 + PSProfile/Classes/PSProfile.Classes.ps1 | 27 +- PSProfile/Private/Encrypt.ps1 | 9 - .../{Decrypt.ps1 => Get-DecryptedValue.ps1} | 2 +- .../Public/Configuration/Import-PSProfile.ps1 | 2 +- .../Start-PSProfileConfigurationHelper.ps1 | 417 ++++++++++++++---- .../Plugin Paths/Add-PSProfilePluginPath.ps1 | 15 +- .../Public/Plugins/Add-PSProfilePlugin.ps1 | 10 +- .../Add-PSProfileProjectPath.ps1 | 8 +- .../Public/Prompts/Add-PSProfilePrompt.ps1 | 12 +- .../Public/Prompts/Get-PSProfilePrompt.ps1 | 21 +- .../Public/Secrets/Get-PSProfileSecret.ps1 | 34 +- .../Remove-PSProfileSymbolicLink.ps1 | 32 +- .../Variables/Remove-PSProfileVariable.ps1 | 34 +- tasks.build.ps1 | 23 +- 16 files changed, 511 insertions(+), 195 deletions(-) delete mode 100644 PSProfile/Private/Encrypt.ps1 rename PSProfile/Private/{Decrypt.ps1 => Get-DecryptedValue.ps1} (90%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5366401..fd2bb57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ * [PSProfile - ChangeLog](#psprofile---changelog) - * [0.2.0 - 2019-09-01](#020---2019-09-01) + * [0.2.0 - 2019-09-02](#020---2019-09-02) * [0.1.9 - 2019-08-26](#019---2019-08-26) * [0.1.8 - 2019-08-26](#018---2019-08-26) * [0.1.7 - 2019-08-25](#017---2019-08-25) @@ -15,21 +15,27 @@ # PSProfile - ChangeLog -## 0.2.0 - 2019-09-01 - -* Added `Start-PSProfileConfigurationHelper` to provide a way -* Added support for multiple Aliases to be removed at once on `Remove-PSProfileCommandAlias`. -* Updated default `SCRTHQ` prompt that comes with the module. -* Added support for NerdFonts and PowerLine switches on the prompts to switch char sets depending on the FontType. -* Added `IncludeVault` switch parameter to `Export-PSProfileConfiguration` to prevent exporting the Secrets Vault by default when creating portable configurations. -* Added `_cleanModules()` method to PSProfile class to remove any null or empty values hanging over and convert any string values to the full hashtable value instead. -* Added special module import process when the `ModuleToImport` is `EditorServicesCommandSuite` so it also automatically registers the available editor commands. -* Cleaned up logic and fixed bugs in the following functions: - * `Add-PSProfileModuleToImport` - * `Remove-PSProfileModuleToImport` - * `Add-PSProfileModuleToInstall` - * `Remove-PSProfileModuleToInstall` - * `Add-PSProfilePlugin` +## 0.2.0 - 2019-09-02 + +* [Issue #2](https://github.com/scrthq/PSProfile/issues/2) + * Added special module import process when the `ModuleToImport` is `EditorServicesCommandSuite` so it also automatically registers the available editor commands. +* [Issue #12](https://github.com/scrthq/PSProfile/issues/12) + * Added `Start-PSProfileConfigurationHelper` to provide an easy way to get started with configuring your PSProfile. +* Miscellaneous + * Added support for multiple Command Aliases to be removed at once with `Remove-PSProfileCommandAlias`. + * Updated default `SCRTHQ` prompt that comes with the module. + * Added support for NerdFonts and PowerLine switches on the prompts to switch char sets depending on the FontType. + * Added `IncludeVault` switch parameter to `Export-PSProfileConfiguration` to prevent exporting the Secrets Vault by default when creating portable configurations. + * Added `_cleanModules()` method to PSProfile class to remove any null or empty values hanging over and convert any string values to the full hashtable value instead. + * Cleaned up logic and fixed bugs in the following functions: + * `Add-PSProfileModuleToImport` + * `Remove-PSProfileModuleToImport` + * `Add-PSProfileModuleToInstall` + * `Remove-PSProfileModuleToInstall` + * `Add-PSProfilePlugin` + * Updated CONTRIBUTING.md with snippet to include for PSProfile developers on their PowerShell profile. + * Refactored `Get-PSProfilePrompt` to return `$null` if a name is specified but does not exist on the current PSProfile configuration. + * Refactored `$PSProfile._loadConfiguration()` to start with the base value of `$Global:PSProfile` if present, otherwise import the existing configuration from file. This is necessary to retain the existing configuration if an action is taken that forces the PSProfile to reload, e.g. adding a new plugin to the configuration. ## 0.1.9 - 2019-08-26 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index de11532..fc5d956 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,6 +4,7 @@ * [Contributing to PSProfile](#contributing-to-psprofile) * [Git and Pull requests](#git-and-pull-requests) + * [Recommendations](#recommendations) * [Overview](#overview) * [Step by Step (High-Level)](#step-by-step-high-level) * [Contributing Guidelines](#contributing-guidelines) @@ -20,6 +21,27 @@ Thank you for your interest in helping PSProfile grow! Below you'll find some gu * Contributions are submitted, reviewed, and accepted using Github pull requests. [Read this article](https://help.github.com/articles/using-pull-requests) for some details. We use the _Fork and Pull_ model, as described there. More info can be found here: [Forking Projects](https://guides.github.com/activities/forking/) * Please make sure to leave the `Allow edits from maintainers` box checked when submitting PR's so that any edits can be made by maintainers of the repo directly to the source branch and into the same PR. More info can be found here: [Allowing changes to a pull request branch created from a fork](https://help.github.com/articles/allowing-changes-to-a-pull-request-branch-created-from-a-fork/#enabling-repository-maintainer-permissions-on-existing-pull-requests) +## Recommendations + +To provide the easiest PSProfile development experience while ensuring normal consoles remain intact, it is recommended to add the following to your PowerShell profile: + +```powershell +$module = if (Test-Path '.\BuildOutput\PSProfile') { + try { + Import-Module '.\BuildOutput\PSProfile' -ErrorAction Stop + } + catch { + Write-Warning "Error(s) when importing PSProfile from the BuildOutput folder:`n$($Error[0])`nFalling back to installed version" + Import-Module PSProfile + } +} +else { + Import-Module PSProfile +} +``` + +This will import the most recently built module from the BuildOutput folder if you start your session in the PSProfile repo root (i.e. if you open the project in your default editor). If any errors are hit during module import, fall back to importing the installed version instead to retain access to PowerTools. + ## Overview ### Step by Step (High-Level) diff --git a/PSProfile/Classes/PSProfile.Classes.ps1 b/PSProfile/Classes/PSProfile.Classes.ps1 index 5f82cad..a9e7db8 100644 --- a/PSProfile/Classes/PSProfile.Classes.ps1 +++ b/PSProfile/Classes/PSProfile.Classes.ps1 @@ -235,21 +235,12 @@ if ($env:AWS_PROFILE) { Write-Host "]" -NoNewline } "`n>> "' - $plugPaths = @() + $plugPaths = @((Join-Path $PSScriptRoot "Plugins")) $curVer = (Import-Metadata (Join-Path $PSScriptRoot "PSProfile.psd1")).ModuleVersion - $this.PluginPaths | Where-Object { $_ -match "[\/\\](Modules|BuildOutput)[\/\\]PSProfile[\/\\]$curVer" -or $_ -notmatch "[\/\\](Modules|BuildOutput)[\/\\]PSProfile[\/\\]\d+\.\d+\.\d+" } | ForEach-Object { + $this.PluginPaths | Where-Object {-not [string]::IsNullOrEmpty($_) -and ($_ -match "[\/\\](Modules|BuildOutput)[\/\\]PSProfile[\/\\]$curVer" -or $_ -notmatch "[\/\\](Modules|BuildOutput)[\/\\]PSProfile[\/\\]\d+\.\d+\.\d+") } | ForEach-Object { $plugPaths += $_ } - @( - $env:PSModulePath.Split([System.IO.Path]::PathSeparator) - (Get-Module PSProfile* | Select-Object -ExpandProperty ModuleBase) - (Join-Path $PSScriptRoot "Plugins") - ) | ForEach-Object { - if ($_ -notin $this.PluginPaths) { - $plugPaths += $_ - } - } - $this.PluginPaths = $plugPaths + $this.PluginPaths = $plugPaths | Select-Object -Unique if (-not ($this.Plugins | Where-Object { $_.Name -eq 'PSProfile.PowerTools' })) { $plugs = @(@{Name = 'PSProfile.PowerTools' }) $this.Plugins | ForEach-Object { @@ -282,7 +273,9 @@ if ($env:AWS_PROFILE) { "MAIN", "Debug" ) - Write-Host "Loading PSProfile alone took $([Math]::Round($this._internal.ProfileLoadDuration.TotalMilliseconds))ms$withRefresh" + if ($env:ShowPSProfileLoadTime -ne $false) { + Write-Host "Loading PSProfile alone took $([Math]::Round($this._internal.ProfileLoadDuration.TotalMilliseconds))ms$withRefresh" + } } [void] Refresh() { $this._log( @@ -358,7 +351,7 @@ if ($env:AWS_PROFILE) { "LoadPrompt", "Verbose" ) - Switch-PSProfilePrompt -Name $this.Settings.DefaultPrompt + $function:prompt = $this.Prompts[$this.Settings.DefaultPrompt] } else { $this._log( @@ -855,7 +848,11 @@ if ($env:AWS_PROFILE) { if ($plugin.ArgumentList) { $importParams['ArgumentList'] = $plugin.ArgumentList } - foreach ($plugPath in $this.PluginPaths) { + [string[]]$pathsToSearch = @($this.PluginPaths) + $env:PSModulePath.Split([System.IO.Path]::PathSeparator) | ForEach-Object { + $pathsToSearch += $_ + } + foreach ($plugPath in $pathsToSearch) { $fullPath = [System.IO.Path]::Combine($plugPath,"$($plugin.Name).ps1") $this._log( "'$($plugin.Name)' Checking path: $fullPath", diff --git a/PSProfile/Private/Encrypt.ps1 b/PSProfile/Private/Encrypt.ps1 deleted file mode 100644 index 7b697c0..0000000 --- a/PSProfile/Private/Encrypt.ps1 +++ /dev/null @@ -1,9 +0,0 @@ -function Encrypt { - param($Item) - if ($Item -is [System.Security.SecureString]) { - $Item - } - elseif ($Item -is [System.String] -and -not [System.String]::IsNullOrWhiteSpace($Item)) { - ConvertTo-SecureString -String $Item -AsPlainText -Force - } -} diff --git a/PSProfile/Private/Decrypt.ps1 b/PSProfile/Private/Get-DecryptedValue.ps1 similarity index 90% rename from PSProfile/Private/Decrypt.ps1 rename to PSProfile/Private/Get-DecryptedValue.ps1 index ab21969..3499e70 100644 --- a/PSProfile/Private/Decrypt.ps1 +++ b/PSProfile/Private/Get-DecryptedValue.ps1 @@ -1,4 +1,4 @@ -function Decrypt { +function Get-DecryptedValue { param($Item) if ($Item -is [System.Security.SecureString]) { [System.Runtime.InteropServices.Marshal]::PtrToStringAuto( diff --git a/PSProfile/Public/Configuration/Import-PSProfile.ps1 b/PSProfile/Public/Configuration/Import-PSProfile.ps1 index 368c2c9..68baefe 100644 --- a/PSProfile/Public/Configuration/Import-PSProfile.ps1 +++ b/PSProfile/Public/Configuration/Import-PSProfile.ps1 @@ -16,6 +16,6 @@ function Import-PSProfile { Param() Process { Write-Verbose "Loading PSProfile configuration!" - $global:PSProfile.Load() + $global:PSProfile._loadConfiguration() } } diff --git a/PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 b/PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 index ab5f082..a1ac87f 100644 --- a/PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 +++ b/PSProfile/Public/Configuration/Start-PSProfileConfigurationHelper.ps1 @@ -11,7 +11,7 @@ function Start-PSProfileConfigurationHelper { #> [CmdletBinding()] Param () - Begin { + Process { Write-Verbose "Starting PSProfile Configuration Helper..." $color = @{ Tip = "Green" @@ -48,20 +48,26 @@ function Start-PSProfileConfigurationHelper { $multi = { .$tip("This accepts multiple answers as comma-separated values, e.g. 1,2,5") } - } - Process { - @( - "" - "Welcome to PSProfile! This Configuration Helper serves as a way to jump-start" - "your PSProfile configuration and increase your workflow productivity quickly." - "" - "You'll be asked a few questions to help with setting up your PSProfile," - "including being provided information around performing the same configuration" - "tasks using the included functions after your initial setup is complete." - "" - "If you have any questions, comments or find any bugs, please open an issue" - "on the PSProfile repo: https://github.com/scrthq/PSProfile/issues/new" - ) | Write-Host + $exit = { + "" | Write-Host + .$header("Changes made to configuration") + if ($changes.Count) { + $changes | Write-Host + "" | Write-Host + "Would you like to save your updated PSProfile configuration?" | Write-Host + $decision = Read-Host "[Y] Yes [N] No [X] Exit" + switch -Regex ($decision) { + "[Yy]" { + Save-PSProfile -Verbose + } + } + } + else { + "None!" | Write-Host + } + "`nExiting Configuration Helper`n" | Write-Host -ForegroundColor Yellow + return + } $legend = { "" | Write-Host .$header("Legend") | Write-Host @@ -71,8 +77,6 @@ function Start-PSProfileConfigurationHelper { .$current("$($color['Current']) - Any existing configuration values for this section") "" | Write-Host } - .$legend - $menu = { "" | Write-Host .$header("Menu") | Write-Host @@ -97,7 +101,8 @@ function Start-PSProfileConfigurationHelper { "[14] Helpers" "[15] Meta" "" - "[*] All concepts" + "[*] All concepts (Default)" + "[H] Hide Help Topics" "" "[X] Exit" "" @@ -105,18 +110,44 @@ function Start-PSProfileConfigurationHelper { $options | Write-Host .$multi "" | Write-Host - Read-Host -Prompt "Enter your choice(s)" + Read-Host -Prompt "Enter your choice(s) (Default: *)" } + + @( + "" + "Welcome to PSProfile! This Configuration Helper serves as a way to jump-start" + "your PSProfile configuration and increase your workflow productivity quickly." + "" + "You'll be asked a few questions to help with setting up your PSProfile," + "including being provided information around performing the same configuration" + "tasks using the included functions after your initial setup is complete." + "" + "If you have any questions, comments or find any bugs, please open an issue" + "on the PSProfile repo: https://github.com/scrthq/PSProfile/issues/new" + ) | Write-Host + .$legend $choices = .$menu + if ([string]::IsNullOrEmpty($choices)) { + $choices = '*' + } + $hideHelpTopics = if ($choices -match "[Hh]") { + $true + } + else { + $false + } if ($choices -match "[Xx]") { - "`nExiting Configuration Helper!`n" | Write-Host -ForegroundColor Yellow + .$exit return } else { - "`nConcepts chosen:" | Write-Host + "`nChoices:" | Write-Host if ($choices -match '\*') { $options | Select-String "^\[\*\]\s+" | Write-Host $resolved = @(1..15) + if ($hideHelpTopics) { + $resolved += 'H' + } } else { $resolved = $choices.Split(',').Trim() | Where-Object { -not [string]::IsNullOrEmpty($_) } @@ -125,15 +156,17 @@ function Start-PSProfileConfigurationHelper { $options | Select-String "^\[$item\]\s+" | Write-Host } } - foreach ($choice in $resolved) { + foreach ($choice in $resolved | Where-Object {$_ -ne 'H'}) { "" | Write-Host $topic = (($options | Select-String "^\[$choice\]\s+") -replace "^\[$choice\]\s+(.*$)",'$1').Trim() - .$header($topic) $helpTopic = 'about_PSProfile_' + ($topic -replace ' ','_') - "Getting the HelpTopic for this concept: $helpTopic" | Write-Host - Get-Help $helpTopic -Category HelpFile - .$tip("To view this conceptual HelpTopic at any time, run the following command:") - .$command("Get-Help $helpTopic") + .$header($topic) + if (-not $hideHelpTopics) { + "Getting the HelpTopic for this concept: $helpTopic" | Write-Host + Get-Help $helpTopic -Category HelpFile + .$tip("To view this conceptual HelpTopic at any time, run the following command:") + .$command("Get-Help $helpTopic") + } "" | Write-Host switch ($choice) { 1 { @@ -166,7 +199,7 @@ function Start-PSProfileConfigurationHelper { $decision = Read-Host "[Y] Yes [N] No [X] Exit" } "[Xx]" { - "`nExiting Configuration Helper!`n" | Write-Host -ForegroundColor Yellow + .$exit return } } @@ -175,20 +208,7 @@ function Start-PSProfileConfigurationHelper { } 2 { if ($Global:PSProfile.ModulesToImport.Count) { - .$current( - ( - ( - $Global:PSProfile.ModulesToImport | ForEach-Object { - if ($_ -is [hashtable]) { - $_.Name - } - else { - $_ - } - } - ) -join ", " - ) - ) + .$current("`n- $((($Global:PSProfile.ModulesToImport|ForEach-Object{if($_ -is [hashtable]){$_.Name}else{$_}} | Sort-Object) -join "`n- "))") } Write-Host "Would you like to add a Module to Import to your PSProfile?" $decision = Read-Host "[Y] Yes [N] No [X] Exit" @@ -214,7 +234,7 @@ function Start-PSProfileConfigurationHelper { $decision = Read-Host "[Y] Yes [N] No [X] Exit" } "[Xx]" { - "`nExiting Configuration Helper!`n" | Write-Host -ForegroundColor Yellow + .$exit return } } @@ -223,20 +243,7 @@ function Start-PSProfileConfigurationHelper { } 3 { if ($Global:PSProfile.ModulesToInstall.Count) { - .$current( - ( - ( - $Global:PSProfile.ModulesToInstall | ForEach-Object { - if ($_ -is [hashtable]) { - $_.Name - } - else { - $_ - } - } - ) -join ", " - ) - ) + .$current("`n- $((($Global:PSProfile.ModulesToInstall|ForEach-Object{if($_ -is [hashtable]){$_.Name}else{$_}} | Sort-Object) -join "`n- "))") } Write-Host "Would you like to add a Module to Install to your PSProfile?" $decision = Read-Host "[Y] Yes [N] No [X] Exit" @@ -262,7 +269,7 @@ function Start-PSProfileConfigurationHelper { $decision = Read-Host "[Y] Yes [N] No [X] Exit" } "[Xx]" { - "`nExiting Configuration Helper!`n" | Write-Host -ForegroundColor Yellow + .$exit return } } @@ -299,7 +306,7 @@ function Start-PSProfileConfigurationHelper { $decision = Read-Host "[Y] Yes [N] No [X] Exit" } "[Xx]" { - "`nExiting Configuration Helper!`n" | Write-Host -ForegroundColor Yellow + .$exit return } } @@ -308,7 +315,7 @@ function Start-PSProfileConfigurationHelper { } 5 { if ($Global:PSProfile.PluginPaths.Count) { - .$current(($Global:PSProfile.PluginPaths -join ", ")) + .$current("`n- $(($Global:PSProfile.PluginPaths | Sort-Object) -join "`n- ")") } Write-Host "Would you like to add an additional Plugin Path to your PSProfile?" .$tip("This is only needed if you have PSProfile plugins in a path outside of your normal PSModulePath") @@ -317,25 +324,25 @@ function Start-PSProfileConfigurationHelper { switch -Regex ($decision) { "[Yy]" { $item1 = Read-Host "Please enter the path to the additional plugin folder" - if ($null -eq (Get-PSProfilePluginPath -Name $item1)) { + if ($null -eq (Get-PSProfilePluginPath -Path $item1)) { if (-not $changeHash.ContainsKey('Plugin Paths')) { $changes.Add("Plugin Paths:") $changeHash['Plugin Paths'] = @() } - .$command("Add-PSProfilePluginPath -Name '$item1'") - Add-PSProfilePluginPath -Name $item1 -Verbose + .$command("Add-PSProfilePluginPath -Path '$item1'") + Add-PSProfilePluginPath -Path $item1 -NoRefresh -Verbose $changes.Add(" - $item1") $changeHash['Plugin Paths'] += $item1 } else { .$warning("Plugin Path '$item1' already exists on your PSProfile configuration! If you would like to overwrite it, run the following command:") - .$command("Add-PSProfilePluginPath -Name '$item1' -Force") + .$command("Add-PSProfilePluginPath -Path '$item1' -Force") } "`nWould you like to add another Plugin Path to your PSProfile?" | Write-Host $decision = Read-Host "[Y] Yes [N] No [X] Exit" } "[Xx]" { - "`nExiting Configuration Helper!`n" | Write-Host -ForegroundColor Yellow + .$exit return } } @@ -344,10 +351,10 @@ function Start-PSProfileConfigurationHelper { } 6 { if ($Global:PSProfile.Plugins.Count) { - .$current(($Global:PSProfile.Plugins.Name -join ", ")) + .$current("`n- $(($Global:PSProfile.Plugins.Name | Sort-Object) -join "`n- ")") } Write-Host "Would you like to add a Plugin to your PSProfile?" - .$tip("Plugins can be either scripts or modules.)") + .$tip("Plugins can be either scripts or modules.") .$tip("Use AD cmdlets? Try adding the plugin 'PSProfile.ADCompleters' to get tab-completion for the Properties parameter on Get-ADUser, Get-ADGroup, and Get-ADComputer!") $decision = Read-Host "[Y] Yes [N] No [X] Exit" do { @@ -360,7 +367,7 @@ function Start-PSProfileConfigurationHelper { $changeHash['Plugins'] = @() } .$command("Add-PSProfilePlugin -Name '$item1'") - Add-PSProfilePlugin -Name $item1 -Verbose + Add-PSProfilePlugin -Name $item1 -NoRefresh -Verbose $changes.Add(" - $item1") $changeHash['Plugins'] += $item1 } @@ -372,7 +379,7 @@ function Start-PSProfileConfigurationHelper { $decision = Read-Host "[Y] Yes [N] No [X] Exit" } "[Xx]" { - "`nExiting Configuration Helper!`n" | Write-Host -ForegroundColor Yellow + .$exit return } } @@ -381,33 +388,33 @@ function Start-PSProfileConfigurationHelper { } 7 { if ($Global:PSProfile.ProjectPaths.Count) { - .$current(($Global:PSProfile.ProjectPaths -join ", ")) + .$current("`n- $(($Global:PSProfile.ProjectPaths | Sort-Object) -join "`n- ")") } - Write-Host "Would you like to add an additional Project Path to your PSProfile?" + Write-Host "Would you like to add a Project Path to your PSProfile?" $decision = Read-Host "[Y] Yes [N] No [X] Exit" do { switch -Regex ($decision) { "[Yy]" { $item1 = Read-Host "Please enter the path to the additional project folder" - if ($null -eq (Get-PSProfileProjectPath -Name $item1)) { + if ($null -eq (Get-PSProfileProjectPath -Path $item1)) { if (-not $changeHash.ContainsKey('Project Paths')) { $changes.Add("Project Paths:") $changeHash['Project Paths'] = @() } - .$command("Add-PSProfileProjectPath -Name '$item1'") - Add-PSProfileProjectPath -Name $item1 -Verbose + .$command("Add-PSProfileProjectPath -Path '$item1'") + Add-PSProfileProjectPath -Path $item1 -NoRefresh -Verbose $changes.Add(" - $item1") $changeHash['Project Paths'] += $item1 } else { .$warning("Project Path '$item1' already exists on your PSProfile configuration! If you would like to overwrite it, run the following command:") - .$command("Add-PSProfileProjectPath -Name '$item1' -Force") + .$command("Add-PSProfileProjectPath -Path '$item1' -Force") } "`nWould you like to add another Project Path to your PSProfile?" | Write-Host $decision = Read-Host "[Y] Yes [N] No [X] Exit" } "[Xx]" { - "`nExiting Configuration Helper!`n" | Write-Host -ForegroundColor Yellow + .$exit return } } @@ -415,40 +422,260 @@ function Start-PSProfileConfigurationHelper { until ($decision -notmatch "[Yy]") } 8 { - + if ($Global:PSProfile.Prompts.Count) { + .$current("`n- $(($Global:PSProfile.Prompts.Keys | Sort-Object) -join "`n- ")") + } + if ($function:prompt -notmatch [Regex]::Escape('# https://go.microsoft.com/fwlink/?LinkID=225750')) { + "It looks like you are using a custom prompt! Would you like to save it to your PSProfile?" | Write-Host + $decision = Read-Host "[Y] Yes [N] No [X] Exit" + $promptSaved = $false + do { + switch -Regex ($decision) { + "[Yy]" { + $item1 = Read-Host "Please enter a friendly name to save this prompt as (ex: MyPrompt)" + if ($null -eq (Get-PSProfilePrompt -Name $item1)) { + if (-not $changeHash.ContainsKey('Prompts')) { + $changes.Add("Prompts:") + $changeHash['Prompts'] = @() + } + .$command("Add-PSProfilePrompt -Name '$item1'") + Add-PSProfilePrompt -Name $item1 -Verbose + $changes.Add(" - $item1") + $changeHash['Prompts'] += $item1 + $promptSaved = $true + } + else { + .$warning("Prompt '$item1' already exists on your PSProfile configuration! If you would like to overwrite it, run the following command:") + .$command("Add-PSProfilePrompt -Name '$item1' -Force") + "`nWould you like to save your prompt as a different name?" | Write-Host + $decision = Read-Host "[Y] Yes [N] No [X] Exit" + } + } + "[Xx]" { + .$exit + return + } + } + } + until ($promptSaved -or $decision -notmatch "[Yy]") + } + else { + "It looks like you are using the default prompt! Skipping prompt configuration for now." | Write-Host + } } 9 { - + if ($Global:PSProfile.ScriptPaths.Count) { + .$current("`n- $(($Global:PSProfile.ScriptPaths | Sort-Object) -join "`n- ")") + } + Write-Host "Would you like to add a Script Path to your PSProfile?" + .$tip("Script paths are invoked during PSProfile load. If you are running any external scripts from your current profile script, this is where you would add them.") + $decision = Read-Host "[Y] Yes [N] No [X] Exit" + do { + switch -Regex ($decision) { + "[Yy]" { + $item1 = Read-Host "Please enter the path of the additional script to add" + if ($null -eq (Get-PSProfileScriptPath -Path $item1)) { + if (-not $changeHash.ContainsKey('Script Paths')) { + $changes.Add("Script Paths:") + $changeHash['Script Paths'] = @() + } + .$command("Add-PSProfileScriptPath -Path '$item1'") + Add-PSProfileScriptPath -Path $item1 -Verbose + $changes.Add(" - $item1") + $changeHash['Script Paths'] += $item1 + } + else { + .$warning("Script Path '$item1' already exists on your PSProfile configuration! If you would like to overwrite it, run the following command:") + .$command("Add-PSProfileScriptPath -Path '$item1' -Force") + } + "`nWould you like to add another Script Path to your PSProfile?" | Write-Host + $decision = Read-Host "[Y] Yes [N] No [X] Exit" + } + "[Xx]" { + .$exit + return + } + } + } + until ($decision -notmatch "[Yy]") } 10 { - + if (($Global:PSProfile.Vault._secrets.GetEnumerator() | Where-Object {$_.Key -ne 'GitCredentials'}).Count) { + .$current("`n- $((($Global:PSProfile.Vault._secrets.GetEnumerator() | Where-Object {$_.Key -ne 'GitCredentials'}).Key | Sort-Object) -join "`n- ")") + } + Write-Host "Would you like to add a Secret to your PSProfile Vault?" + .$tip("Vault Secrets can be either a PSCredential object or a SecureString such as an API key stored with a friendly name to recall them with.") + .$warning("Vault Secrets are encrypted using the Data Protection API, which is not as secure on non-Windows machines and unsupported in PowerShell 6.0-6.1. For more details, please see the Pull Request covering the topic where support was re-added in PowerShell Core: https://github.com/PowerShell/PowerShell/pull/9199") + $decision = Read-Host "[Y] Yes [N] No [X] Exit" + do { + switch -Regex ($decision) { + "[Yy]" { + do { + "What type of Secret would you like to add?" | Write-Host + $secretType = Read-Host "[P] PSCredential [S] SecureString [C] Cancel" + } + until ($secretType -match "[Pp|Ss|Cc]") + if ($secretType -match "[Pp]") { + "Please enter the credentials you would like to store in the Secrets Vault" | Write-Host + $creds = Get-Credential + if ($null -eq (Get-PSProfileSecret -Name $creds.UserName)) { + if (-not $changeHash.ContainsKey('Secrets')) { + $changes.Add("Secrets:") + $changeHash['Secrets'] = @() + } + .$command("Add-PSProfileSecret -Credential (Get-Credential)") + Add-PSProfileSecret -Credential $creds -Verbose + $changes.Add(" - $($creds.UserName)") + $changeHash['Secrets'] += $creds.UserName + } + else { + .$warning("Secret '$item1' already exists on your PSProfile configuration! If you would like to overwrite it, run the following command:") + .$command("Add-PSProfileSecret -Credential (Get-Credential) -Force") + } + "`nWould you like to add another Secret to your PSProfile Fault?" | Write-Host + $decision = Read-Host "[Y] Yes [N] No [X] Exit" + } + elseif ($secretType -match "[Ss]") { + $item1 = Read-Host "Please enter the name you would like to store the secret as (ex: SecretAPIKey)" + $item2 = Read-Host -AsSecureString "Please enter the secret to store as a SecureString" + if ($null -eq (Get-PSProfileSecret -Name $item1)) { + if (-not $changeHash.ContainsKey('Secrets')) { + $changes.Add("Secrets:") + $changeHash['Secrets'] = @() + } + .$command("Add-PSProfileSecret -Name '$item1' -SecureString (Read-Host -AsSecureString 'Enter SecureString')") + Add-PSProfileSecret -Name $item1 -SecureString $item2 -Verbose + $changes.Add(" - $item1") + $changeHash['Secrets'] += $item1 + } + else { + .$warning("Secret '$item1' already exists on your PSProfile configuration! If you would like to overwrite it, run the following command:") + .$command("Add-PSProfileSecret -Name '$item1' -SecureString (Read-Host -AsSecureString 'Enter SecureString') -Force") + } + "`nWould you like to add another Secret to your PSProfile Fault?" | Write-Host + $decision = Read-Host "[Y] Yes [N] No [X] Exit" + } + else { + $decision = $secretType + } + } + "[Xx]" { + .$exit + return + } + } + } + until ($decision -notmatch "[Yy]") } 11 { - + if ($Global:PSProfile.SymbolicLinks.Keys.Count) { + .$current("`n$(($Global:PSProfile.SymbolicLinks | Out-String).Trim())") + } + Write-Host "Would you like to add a Symbolic Link to your PSProfile?" + $decision = Read-Host "[Y] Yes [N] No [X] Exit" + do { + switch -Regex ($decision) { + "[Yy]" { + $item1 = Read-Host "Please enter the path you would like to add an symbolic link for (ex: C:\Users\$env:USERNAME)" + $item2 = Read-Host "Please enter the path of the symbolic link you would like to target the previous path with (ex: C:\Home)" + if ($null -eq (Get-PSProfileSymbolicLink -LinkPath $item2)) { + if (-not $changeHash.ContainsKey('Symbolic Links')) { + $changes.Add("Symbolic Links:") + $changeHash['Symbolic Links'] = @{ } + } + .$command("Add-PSProfileSymbolicLink -ActualPath '$item1' -LinkPath '$item2'") + Add-PSProfileSymbolicLink -ActualPath $item1 -LinkPath $item2 -Verbose + $changes.Add(" - ActualPath: $item1") + $changes.Add(" LinkPath: $item2") + $changeHash['Symbolic Links'][$item1] = $item2 + } + else { + .$warning("Symbolic Link '$item2' already exists on your PSProfile configuration! If you would like to overwrite it, run the following command:") + .$command("Add-PSProfileSymbolicLink -ActualPath '$item1' -LinkPath '$item2' -Force") + } + "`nWould you like to add another Symbolic Link to your PSProfile?" | Write-Host + $decision = Read-Host "[Y] Yes [N] No [X] Exit" + } + "[Xx]" { + .$exit + return + } + } + } + until ($decision -notmatch "[Yy]") } 12 { - + if ($Global:PSProfile.Variables.Environment.Keys.Count -or $Global:PSProfile.Variables.Global.Keys.Count) { + .$current("`n`n~~ ENVIRONMENT ~~`n$(($Global:PSProfile.Variables.Environment | Out-String).Trim())`n`n~~ GLOBAL ~~`n$(($Global:PSProfile.Variables.Global | Out-String).Trim())") + } + Write-Host "Would you like to add a Variable to your PSProfile?" + $decision = Read-Host "[Y] Yes [N] No [X] Exit" + do { + switch -Regex ($decision) { + "[Yy]" { + "Please enter the scope of the Variable to add" | Write-Host + $s = Read-Host "[E] Environment [G] Global" + $scope = switch -RegEx ($s) { + "[Ee]" { + 'Environment' + } + "[Gg]" { + 'Global' + } + } + $item1 = Read-Host "Please enter the name of the variable to add (ex: AWS_PROFILE)" + $item2 = Read-Host "Please enter the value to set for variable '$item1' (ex: production)" + if ($null -eq (Get-PSProfileVariable -Scope $scope -Name $item1)) { + if (-not $changeHash.ContainsKey('Variables')) { + $changes.Add("Variables:") + $changeHash['Variables'] = @{ + Environment = @{} + Global = @{} + } + } + .$command("Add-PSProfileVariable -Scope '$scope' -Name '$item1' -Value '$item2'") + Add-PSProfileVariable -Scope $scope -Name $item1 -Value $item2 -Verbose + $changes.Add(" - Scope: $scope") + $changes.Add(" Name: $item1") + $changes.Add(" Value: $item2") + $changeHash['Variables'][$scope][$item1] = $item2 + } + else { + .$warning("Variable '$item1' already exists at scope '$scope' on your PSProfile configuration! If you would like to overwrite it, run the following command:") + .$command("Add-PSProfileVariable -Scope '$scope' -Name '$item1' -Value '$item2' -Force") + } + "`nWould you like to add another Variable to your PSProfile?" | Write-Host + $decision = Read-Host "[Y] Yes [N] No [X] Exit" + } + "[Xx]" { + .$exit + return + } + } + } + until ($decision -notmatch "[Yy]") } 13 { - + "Configuration functions are meant to interact with the PSProfile configuration directly, so there is nothing to configure with this Helper! Please see the HelpTopic '$helpTopic' for more info:" | Write-Host + .$command("Get-Help $helpTopic") + "" | Write-Host + Read-Host "Press [Enter] to continue" } 14 { - + "Helper functions are meant to interact for use within prompts or add Log Events to PSProfile, so there is nothing to configure with this Helper! Please see the HelpTopic '$helpTopic' for more info:" | Write-Host + .$command("Get-Help $helpTopic") + "" | Write-Host + Read-Host "Press [Enter] to continue" + } + 15 { + "Meta functions are meant to provide information about PSProfile itself, so there is nothing to configure with this Helper! Please see the HelpTopic '$helpTopic' for more info:" | Write-Host + .$command("Get-Help $helpTopic") + "" | Write-Host + Read-Host "Press [Enter] to continue" } } } - .$header("Changes made to configuration") - $changes | Write-Host - "" | Write-Host - "Would you like to save your PSProfile configuration?" | Write-Host - $decision = Read-Host "[Y] Yes [N] No [X] Exit" - switch -Regex ($decision) { - "[Yy]" { - Save-PSProfile -Verbose - } - } - "`nConfiguration Helper complete! Exiting`n" | Write-Host -ForegroundColor Yellow - return + .$exit } } } diff --git a/PSProfile/Public/Plugin Paths/Add-PSProfilePluginPath.ps1 b/PSProfile/Public/Plugin Paths/Add-PSProfilePluginPath.ps1 index c2d6f93..c2b6f24 100644 --- a/PSProfile/Public/Plugin Paths/Add-PSProfilePluginPath.ps1 +++ b/PSProfile/Public/Plugin Paths/Add-PSProfilePluginPath.ps1 @@ -10,7 +10,7 @@ function Add-PSProfilePluginPath { The path of the folder to add to your $PSProfile.PluginPaths. This path should contain PSProfile.Plugins .PARAMETER NoRefresh - If $true, skips refreshing your PSProfile after updating plugin paths. + If $true, skips reloading your PSProfile after updating. .PARAMETER Save If $true, saves the updated PSProfile after updating. @@ -42,19 +42,24 @@ function Add-PSProfilePluginPath { Process { foreach ($p in $Path) { $fP = (Resolve-Path $p).Path + [string[]]$base = @() + $Global:PSProfile.PluginPaths | Where-Object {-not [string]::IsNullOrEmpty($_)} | ForEach-Object { + $base += $_ + } if ($Global:PSProfile.PluginPaths -notcontains $fP) { Write-Verbose "Adding PluginPath to PSProfile: $fP" - $Global:PSProfile.PluginPaths += $fP + $base += $fP } else { Write-Verbose "PluginPath already in PSProfile: $fP" } - } - if (-not $NoRefresh) { - Import-PSProfile + $Global:PSProfile.PluginPaths = $base } if ($Save) { Save-PSProfile } + if (-not $NoRefresh) { + Import-PSProfile -Verbose:$false + } } } diff --git a/PSProfile/Public/Plugins/Add-PSProfilePlugin.ps1 b/PSProfile/Public/Plugins/Add-PSProfilePlugin.ps1 index a534bfa..bb21dac 100644 --- a/PSProfile/Public/Plugins/Add-PSProfilePlugin.ps1 +++ b/PSProfile/Public/Plugins/Add-PSProfilePlugin.ps1 @@ -12,6 +12,9 @@ function Add-PSProfilePlugin { .PARAMETER ArgumentList Any arguments that need to be passed to the plugin on import, such as a hashtable to process. + .PARAMETER NoRefresh + If $true, skips reloading your PSProfile after updating. + .PARAMETER Save If $true, saves the updated PSProfile after updating. @@ -30,6 +33,9 @@ function Add-PSProfilePlugin { $ArgumentList, [Parameter()] [Switch] + $NoRefresh, + [Parameter()] + [Switch] $Save ) Process { @@ -51,7 +57,9 @@ function Add-PSProfilePlugin { if ($Save) { Save-PSProfile } - Import-PSProfile -Verbose:$false + if (-not $NoRefresh) { + Import-PSProfile -Verbose:$false + } } } diff --git a/PSProfile/Public/Project Paths/Add-PSProfileProjectPath.ps1 b/PSProfile/Public/Project Paths/Add-PSProfileProjectPath.ps1 index a663649..f3d9458 100644 --- a/PSProfile/Public/Project Paths/Add-PSProfileProjectPath.ps1 +++ b/PSProfile/Public/Project Paths/Add-PSProfileProjectPath.ps1 @@ -10,7 +10,7 @@ function Add-PSProfileProjectPath { The path of the folder to add to your $PSProfile.ProjectPaths. This path should contain Git repo folders underneath it. .PARAMETER NoRefresh - If $true, skips refreshing your PSProfile after updating project paths. + If $true, skips refreshing your PSProfile after updating. .PARAMETER Save If $true, saves the updated PSProfile after updating. @@ -50,11 +50,11 @@ function Add-PSProfileProjectPath { Write-Verbose "ProjectPath already in PSProfile: $fP" } } - if (-not $NoRefresh) { - Update-PSProfileConfig - } if ($Save) { Save-PSProfile } + if (-not $NoRefresh) { + Update-PSProfileConfig + } } } diff --git a/PSProfile/Public/Prompts/Add-PSProfilePrompt.ps1 b/PSProfile/Public/Prompts/Add-PSProfilePrompt.ps1 index 8c58305..c9bc4e9 100644 --- a/PSProfile/Public/Prompts/Add-PSProfilePrompt.ps1 +++ b/PSProfile/Public/Prompts/Add-PSProfilePrompt.ps1 @@ -15,6 +15,9 @@ function Add-PSProfilePrompt { .PARAMETER SetAsDefault If $true, sets the prompt as default by updated $PSProfile.Settings.DefaultPrompt. + .PARAMETER Save + If $true, saves the updated PSProfile after updating. + .EXAMPLE Add-PSProfilePrompt -Name Demo -Content '"PS > "' @@ -30,7 +33,10 @@ function Add-PSProfilePrompt { $Content, [Parameter()] [switch] - $SetAsDefault + $SetAsDefault, + [Parameter()] + [switch] + $Save ) Process { if ($null -eq $Name) { @@ -49,7 +55,9 @@ function Add-PSProfilePrompt { if ($SetAsDefault) { $global:PSProfile.Settings.DefaultPrompt = $Name } - Save-PSProfile + if ($Save) { + Save-PSProfile + } } } } diff --git a/PSProfile/Public/Prompts/Get-PSProfilePrompt.ps1 b/PSProfile/Public/Prompts/Get-PSProfilePrompt.ps1 index 05871e8..a70e4fd 100644 --- a/PSProfile/Public/Prompts/Get-PSProfilePrompt.ps1 +++ b/PSProfile/Public/Prompts/Get-PSProfilePrompt.ps1 @@ -36,7 +36,18 @@ function Get-PSProfilePrompt { [Switch] $Raw ) - Begin { + Process { + $pContents = if ($PSBoundParameters.ContainsKey('Name')) { + if ($Global:PSProfile.Prompts.ContainsKey($Name)) { + $Global:PSProfile.Prompts[$Name] + } + else { + return + } + } + else { + $function:prompt + } $pssa = if ($NoPSSA -or $null -eq (Get-Module PSScriptAnalyzer* -ListAvailable)) { $false } @@ -44,14 +55,6 @@ function Get-PSProfilePrompt { $true Import-Module PSScriptAnalyzer -Verbose:$false } - $pContents = if ($PSBoundParameters.ContainsKey('Name')) { - $Global:PSProfile.Prompts[$Name] - } - else { - (Get-Command prompt).Definition - } - } - Process { Write-Verbose "Getting current prompt" $i = 0 $lws = $null diff --git a/PSProfile/Public/Secrets/Get-PSProfileSecret.ps1 b/PSProfile/Public/Secrets/Get-PSProfileSecret.ps1 index 74a7514..5b3193f 100644 --- a/PSProfile/Public/Secrets/Get-PSProfileSecret.ps1 +++ b/PSProfile/Public/Secrets/Get-PSProfileSecret.ps1 @@ -9,26 +9,52 @@ function Get-PSProfileSecret { .PARAMETER Name The name of the Secret you would like to retrieve from the Vault. + .PARAMETER AsPlainText + If $true and Confirm:$true, returns the decrypted password if the secret is a PSCredential object or the plain-text string if a SecureString. Requires confirmation. + + .PARAMETER Force + If $true and AsPlainText is $true, bypasses Confirm prompt and returns the plain-text password or decrypted SecureString. + .EXAMPLE Get-PSProfileSecret -Name MyApiKey Gets the Secret named 'MyApiKey' from the $PSProfile.Vault. #> - [CmdletBinding()] + [CmdletBinding(SupportsShouldProcess,ConfirmImpact = "High")] Param( [parameter(Mandatory,Position = 0)] [String] - $Name + $Name, + [parameter()] + [Switch] + $AsPlainText, + [parameter()] + [Switch] + $Force ) Process { Write-Verbose "Getting Secret '$Name' from `$PSProfile.Vault" - $global:PSProfile.Vault.GetSecret($Name) + $sec = $global:PSProfile.Vault.GetSecret($Name) + if ($AsPlainText -and ($Force -or $PSCmdlet.ShouldProcess("Return plain-text value for Secret '$Name'"))) { + if ($sec -is [pscredential]) { + [PSCustomObject]@{ + UserName = $sec.UserName + Password = $sec.GetNetworkCredential().Password + } + } + else { + Get-DecryptedValue $sec + } + } + else { + $sec + } } } Register-ArgumentCompleter -CommandName Get-PSProfileSecret -ParameterName Name -ScriptBlock { param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) - $Global:PSProfile.Vault._secrets.Keys | Where-Object {$_ -like "$wordToComplete*"} | ForEach-Object { + $Global:PSProfile.Vault._secrets.Keys | Where-Object {$_ -notin @('GitCredentials','PSCredentials','SecureStrings') -and $_ -like "$wordToComplete*"} | ForEach-Object { [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) } } diff --git a/PSProfile/Public/Symbolic Links/Remove-PSProfileSymbolicLink.ps1 b/PSProfile/Public/Symbolic Links/Remove-PSProfileSymbolicLink.ps1 index 6f207c0..5746b72 100644 --- a/PSProfile/Public/Symbolic Links/Remove-PSProfileSymbolicLink.ps1 +++ b/PSProfile/Public/Symbolic Links/Remove-PSProfileSymbolicLink.ps1 @@ -23,7 +23,7 @@ function Remove-PSProfileSymbolicLink { [CmdletBinding(SupportsShouldProcess,ConfirmImpact = "High")] Param ( [Parameter(Mandatory,Position = 0)] - [String] + [String[]] $LinkPath, [Parameter()] [Switch] @@ -33,20 +33,26 @@ function Remove-PSProfileSymbolicLink { $Save ) Process { - if ($PSCmdlet.ShouldProcess("Removing '$LinkPath' from `$PSProfile.SymbolicLinks")) { - Write-Verbose "Removing '$LinkPath' from `$PSProfile.SymbolicLinks" - @($LinkPath,(Resolve-Path $LinkPath).Path) | Select-Object -Unique | ForEach-Object { - if ($Global:PSProfile.SymbolicLinks.ContainsKey($_)) { - $Global:PSProfile.SymbolicLinks.Remove($_) + foreach ($path in $LinkPath) { + if ($PSCmdlet.ShouldProcess("Removing '$path' from `$PSProfile.SymbolicLinks")) { + Write-Verbose "Removing '$path' from `$PSProfile.SymbolicLinks" + $paths = @($path) + if (Test-Path $path) { + $paths += (Resolve-Path $path).Path + } + $paths | Select-Object -Unique | ForEach-Object { + if ($Global:PSProfile.SymbolicLinks.ContainsKey($_)) { + $Global:PSProfile.SymbolicLinks.Remove($_) + } + } + if ($Force -and (Test-Path $path)) { + Write-Verbose "Removing SymbolicLink: $path" + Remove-Item $path -Force } } - if ($Force -and (Test-Path $LinkPath)) { - Write-Verbose "Removing SymbolicLink: $LinkPath" - Remove-Item $LinkPath -Force - } - if ($Save) { - Save-PSProfile - } + } + if ($Save) { + Save-PSProfile } } } diff --git a/PSProfile/Public/Variables/Remove-PSProfileVariable.ps1 b/PSProfile/Public/Variables/Remove-PSProfileVariable.ps1 index 6ab072f..f3bb430 100644 --- a/PSProfile/Public/Variables/Remove-PSProfileVariable.ps1 +++ b/PSProfile/Public/Variables/Remove-PSProfileVariable.ps1 @@ -12,6 +12,9 @@ function Remove-PSProfileVariable { .PARAMETER Scope The scope of the Variable to remove between Environment or Global. + .PARAMETER Force + If $true, also removes the variable from the current session at the specified scope. + .PARAMETER Save If $true, saves the updated PSProfile after updating. @@ -27,22 +30,37 @@ function Remove-PSProfileVariable { [String] $Scope, [Parameter(Mandatory,Position = 1)] - [String] + [String[]] $Name, [Parameter()] [Switch] + $Force, + [Parameter()] + [Switch] $Save ) Process { - if ($PSCmdlet.ShouldProcess("Removing $Scope variable '$Name' from `$PSProfile.Variables")) { - Write-Verbose "Removing $Scope variable '$Name' from `$PSProfile.Variables" - if ($Global:PSProfile.Variables[$Scope].ContainsKey($Name)) { - $Global:PSProfile.Variables[$Scope].Remove($Name) - } - if ($Save) { - Save-PSProfile + foreach ($item in $Name) { + if ($PSCmdlet.ShouldProcess("Removing $Scope variable '$item' from `$PSProfile.Variables")) { + Write-Verbose "Removing $Scope variable '$item' from `$PSProfile.Variables" + if ($Global:PSProfile.Variables[$Scope].ContainsKey($item)) { + $Global:PSProfile.Variables[$Scope].Remove($item) + } + if ($Force) { + switch ($Scope) { + Environment { + Remove-Item "Env:\$item" + } + Global { + Remove-Variable -Name $item -Scope Global + } + } + } } } + if ($Save) { + Save-PSProfile + } } } diff --git a/tasks.build.ps1 b/tasks.build.ps1 index fd9461a..96e4554 100644 --- a/tasks.build.ps1 +++ b/tasks.build.ps1 @@ -69,6 +69,17 @@ task Build Clean,{ Write-BuildLog 'Creating psm1...' $psm1 = New-Item -Path $TargetPSM1Path -ItemType File -Force + $psm1Header = @( + '[CmdletBinding()]' + 'Param (' + ' [parameter(Position = 0)]' + ' [bool]' + ' $ShowLoadTime = $true' + ')' + '$env:ShowPSProfileLoadTime = $ShowLoadTime' + ) -join "`n" + $psm1Header | Add-Content -Path $psm1 -Encoding UTF8 + foreach ($scope in @('Classes','Private','Public')) { $gciPath = Join-Path $SourceModuleDirectory $scope if (Test-Path $gciPath) { @@ -96,18 +107,6 @@ task Build Clean,{ Get-ChildItem -Path $SourceModuleDirectory -Directory | Where-Object {$_.BaseName -notin @('Classes','Private','Public')} | ForEach-Object { Copy-Item $_.FullName -Destination $TargetVersionDirectory -Container -Recurse } - <# $sourceManifestPath = Join-Path $SourceModuleDirectory 'Configuration.psd1' - if (Test-Path $sourceManifestPath) { - Import-Module Configuration - $curVer = (Import-PowerShellDataFile $sourceManifestPath).ModuleVersion - if ([Version]$ModuleVersion -ne [Version]$curVer) { - Update-ModuleManifest -Path $sourceManifestPath -ModuleVersion $ModuleVersion - } - Copy-Item $sourceManifestPath -Destination $TargetVersionDirectory - if ([Version]$ModuleVersion -ne [Version]$curVer) { - Update-ModuleManifest -Path $sourceManifestPath -ModuleVersion $curVer - } - } #> # Copy over manifest Copy-Item -Path (Join-Path $SourceModuleDirectory "$($ModuleName).psd1") -Destination $TargetVersionDirectory From 272649079415abbbd12b554a59cd6e7fe81fa517 Mon Sep 17 00:00:00 2001 From: Nate Ferrell Date: Mon, 2 Sep 2019 22:08:03 -0500 Subject: [PATCH 13/13] final updates before the v0.2.0 release --- CHANGELOG.md | 3 +++ PSProfile/Classes/PSProfile.Classes.ps1 | 31 +++++++++++++++++++++---- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fd2bb57..d46c7cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,8 @@ * Added special module import process when the `ModuleToImport` is `EditorServicesCommandSuite` so it also automatically registers the available editor commands. * [Issue #12](https://github.com/scrthq/PSProfile/issues/12) * Added `Start-PSProfileConfigurationHelper` to provide an easy way to get started with configuring your PSProfile. +* [Issue #6](https://github.com/scrthq/PSProfile/issues/6) + * Added `PSReadline` key to `$PSProfile.Settings` (Settings management in development still.) * Miscellaneous * Added support for multiple Command Aliases to be removed at once with `Remove-PSProfileCommandAlias`. * Updated default `SCRTHQ` prompt that comes with the module. @@ -36,6 +38,7 @@ * Updated CONTRIBUTING.md with snippet to include for PSProfile developers on their PowerShell profile. * Refactored `Get-PSProfilePrompt` to return `$null` if a name is specified but does not exist on the current PSProfile configuration. * Refactored `$PSProfile._loadConfiguration()` to start with the base value of `$Global:PSProfile` if present, otherwise import the existing configuration from file. This is necessary to retain the existing configuration if an action is taken that forces the PSProfile to reload, e.g. adding a new plugin to the configuration. + * Updated `$PSProfile._loadPrompt()` method to set the value of `$function:prompt` directly instead of calling `Switch-PSProfilePrompt` to reduce overhead. ## 0.1.9 - 2019-08-26 diff --git a/PSProfile/Classes/PSProfile.Classes.ps1 b/PSProfile/Classes/PSProfile.Classes.ps1 index a9e7db8..85fb04b 100644 --- a/PSProfile/Classes/PSProfile.Classes.ps1 +++ b/PSProfile/Classes/PSProfile.Classes.ps1 @@ -148,6 +148,10 @@ class PSProfile { Default = "AWS: " } } + PSReadline = @{ + Options = @{} + KeyHandlers = @{} + } } $this.RefreshFrequency = (New-TimeSpan -Hours 1).ToString() $this.LastRefresh = [datetime]::Now.AddHours(-2) @@ -283,7 +287,7 @@ if ($env:AWS_PROFILE) { "MAIN", "Verbose" ) - $this._cleanModules() + $this._cleanConfig() $this._findProjects() $this._installModules() $this._createSymbolicLinks() @@ -312,13 +316,18 @@ if ($env:AWS_PROFILE) { } return $content } - hidden [void] _cleanModules() { + hidden [void] _cleanConfig() { $this._log( "SECTION START", - "CleanModules", + "CleanConfig", "Debug" ) foreach ($section in @('ModulesToImport','ModulesToInstall')) { + $this._log( + "[$section] Cleaning section", + "CleanConfig", + "Verbose" + ) [hashtable[]]$final = @() $this.$section | Where-Object {$_ -is [hashtable] -and $_.Name} | ForEach-Object { $final += $_ @@ -326,16 +335,28 @@ if ($env:AWS_PROFILE) { $this.$section | Where-Object {$_ -is [string]} | ForEach-Object { $this._log( "[$section] Converting module string to hashtable: $_", - "CleanModules", + "CleanConfig", "Verbose" ) $final += @{Name = $_} } $this.$section = $final } + foreach ($section in @('ScriptPaths','PluginPaths','ProjectPaths')) { + $this._log( + "[$section] Cleaning section", + "CleanConfig", + "Verbose" + ) + [string[]]$final = @() + $this.$section | Where-Object {-not [string]::IsNullOrEmpty($_)} | ForEach-Object { + $final += $_ + } + $this.$section = $final + } $this._log( "SECTION END", - "CleanModules", + "CleanConfig", "Debug" ) }