2021-01-15 00:23:51 +00:00
|
|
|
[CmdletBinding(SupportsShouldProcess)]param(
|
2021-04-23 17:41:59 +00:00
|
|
|
[switch]$WriteInitScript,
|
|
|
|
[string]$CustomInitScriptPath,
|
2021-01-15 00:23:51 +00:00
|
|
|
[switch]$sudo,
|
|
|
|
[switch]$RemoveOnly,
|
|
|
|
[switch]$ShowSkipped,
|
|
|
|
[switch]$Force,
|
|
|
|
[switch]$NoGitAction,
|
|
|
|
[string]$GitURL = 'https://code.lksz.me/lksz/PowerShell_Scripts',
|
|
|
|
[Parameter(DontShow)]
|
2021-04-23 17:41:59 +00:00
|
|
|
[string]$My_PSScriptRoot = $MyPSScriptRoot,
|
|
|
|
[switch]$NoReloadScripts
|
2021-01-15 00:23:51 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
2021-10-19 01:41:15 +00:00
|
|
|
function LoadProfileCodeFunctions {
|
2021-01-15 00:23:51 +00:00
|
|
|
#######################################################################
|
|
|
|
## ProfileCode function (source) will contain the code to be written
|
|
|
|
#######################################################################
|
|
|
|
function ProfileCode_pre_common {
|
|
|
|
# # If TMUX isn't loaded, start byobu, then exit this script (and current shell)
|
|
|
|
# if ( -not ( Test-Path env:TMUX ) ) { byobu; exit }
|
|
|
|
}
|
|
|
|
#######################################################################
|
|
|
|
## common Profile Code - receommended not to change this
|
|
|
|
## Code will be loaded from profile.d sub-directory after this.
|
|
|
|
#######################################################################
|
|
|
|
function ProfileCode_post_common {
|
|
|
|
# This loads the personal profile section from the $MyPSScriptRoot/profile.d directory
|
|
|
|
Get-Command Reload-MyScripts -ErrorAction SilentlyContinue | ForEach-Object { . $_.Name }
|
|
|
|
}
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
## ProfileCode_common (source) containing mandatory code for $PROFILE
|
|
|
|
#######################################################################
|
2021-04-23 17:41:59 +00:00
|
|
|
function ProfileCode_common {[CmdletBinding()]param()
|
|
|
|
function Get-PowerShellPath {[CmdletBinding()]param()
|
2021-06-29 13:43:27 +00:00
|
|
|
Get-Process -PID $PID | ForEach-Object { $_.Path, $_.Parent.Path } | Where-Object { $_ -match $('(?:powershell|pwsh)(?:.exe)?' + "`$") } | Select-Object -First 1
|
2021-01-15 00:23:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function ConvertTo-Base64 {
|
2021-06-29 13:43:27 +00:00
|
|
|
param([string]$String,[switch]$AsPowershellCommandLine)
|
|
|
|
return "$(if($AsPowershellCommandLine){"$(Get-PowerShellPath) -EncodedCommand "} )$([Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($String)))"
|
|
|
|
}
|
|
|
|
|
2021-06-29 14:35:25 +00:00
|
|
|
function Get-TempPath {
|
|
|
|
#New-TemporaryFile | ForEach-Object { Remove-Item $_; $_.DirectoryName }
|
|
|
|
[System.IO.Path]::GetTempPath()
|
|
|
|
}
|
|
|
|
|
2021-06-29 13:43:27 +00:00
|
|
|
class SessionData {
|
|
|
|
static [hashtable]$Data = [ordered]@{}
|
|
|
|
static [string]$Path = $null
|
|
|
|
|
|
|
|
static [void] Init() {
|
|
|
|
if( -not [SessionData]::Data.SessionID ) {
|
2021-06-29 14:35:25 +00:00
|
|
|
if( Get-Command -Name Get-CimInstance -ErrorAction SilentlyContinue ) {
|
|
|
|
[SessionData]::Data.SessionID =
|
|
|
|
Get-CimInstance -ClassName Win32_Service -Filter 'State="Running" AND DisplayName like "%[_]%"' -Property 'DisplayName','Name' |
|
|
|
|
Select-Object -ExpandProperty DisplayName |
|
|
|
|
ForEach-Object {
|
|
|
|
$_ -split '_' | Select-Object -Last 1
|
|
|
|
} |
|
|
|
|
Where-Object { $_ -notin ('agent') } |
|
2021-06-29 14:45:29 +00:00
|
|
|
Select-Object -First 1
|
2021-06-29 14:35:25 +00:00
|
|
|
} else {
|
|
|
|
$local:p = Get-Process -PID $global:PID
|
|
|
|
$local:t_p = $null
|
|
|
|
do {
|
|
|
|
$t_p = $null
|
|
|
|
if( $p.Parent.Id ) {
|
|
|
|
$t_p = Get-Process -Id $($p.Parent.Id) | Where-Object StartTime
|
|
|
|
}
|
|
|
|
if( $t_p ) {
|
|
|
|
$p = $t_p
|
|
|
|
}
|
|
|
|
} while ($t_p)
|
|
|
|
[SessionData]::Data.SessionID = "$(
|
|
|
|
$p.StartTime.ToString("yyyyMMddHHmmss")
|
|
|
|
)-$(
|
|
|
|
$p.SessionId
|
|
|
|
)"
|
|
|
|
}
|
2021-06-29 13:43:27 +00:00
|
|
|
[SessionData]::Data.CreateTimestamp = Get-Date
|
2021-06-29 14:35:25 +00:00
|
|
|
|
|
|
|
[SessionData]::Path = Join-Path $(Get-TempPath) "session.store.$([SessionData]::Data.SessionID).xmlcli"
|
2021-06-29 13:43:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-29 14:35:25 +00:00
|
|
|
static [string] GetSessionID() {
|
2021-06-29 13:43:27 +00:00
|
|
|
if( -not [SessionData]::Data.SessionID ) {
|
|
|
|
[SessionData]::Init()
|
|
|
|
|
|
|
|
[SessionData]::Save()
|
|
|
|
}
|
|
|
|
return [SessionData]::Data.SessionID
|
|
|
|
}
|
|
|
|
|
|
|
|
static [void] Save() {
|
|
|
|
if( -not [SessionData]::Path ) { [SessionData]::Init() }
|
|
|
|
|
|
|
|
[SessionData]::Data | Export-Clixml -Path $([SessionData]::Path)
|
|
|
|
}
|
|
|
|
|
|
|
|
static [void] Load() {
|
|
|
|
if( -not [SessionData]::Path ) { [SessionData]::Init() }
|
|
|
|
|
2021-06-29 22:46:33 +00:00
|
|
|
if( Test-Path $([SessionData]::Path) ) {
|
|
|
|
[SessionData]::Data = Import-Clixml -Path $([SessionData]::Path)
|
|
|
|
}
|
2021-06-29 13:43:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static [void] Set([string]$Name,[object]$Value) {
|
|
|
|
$null = [SessionData]::GetSessionID()
|
|
|
|
[SessionData]::Data[$Name] = $Value
|
|
|
|
[SessionData]::Save()
|
|
|
|
}
|
|
|
|
|
|
|
|
static [object] Get([string]$Name,[object]$DefaultValue=$null) {
|
|
|
|
[SessionData]::Load()
|
|
|
|
if( -not [SessionData]::Data.ContainsKey($Name) ) {
|
|
|
|
if( $DefaultValue ) {
|
|
|
|
[SessionData]::Set($Name,$DefaultValue)
|
|
|
|
} else {
|
|
|
|
return $DefaultValue
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return [SessionData]::Data[$Name]
|
|
|
|
}
|
2021-01-15 00:23:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function Invoke-ExpressionEx {
|
|
|
|
[CmdletBinding(SupportsShouldProcess)]param(
|
|
|
|
[switch]$sudo,
|
|
|
|
[switch]$Force,
|
|
|
|
[string]$Function,
|
|
|
|
[switch]$MarshalOutput,
|
2021-10-12 00:41:46 +00:00
|
|
|
[string[]]$sudoArgs,
|
2021-01-15 00:23:51 +00:00
|
|
|
[Parameter(Position = 1, ValueFromRemainingArguments = $true)]
|
|
|
|
[string[]]$expr
|
|
|
|
)
|
|
|
|
|
|
|
|
function do_sudo {
|
|
|
|
[CmdletBinding()]param(
|
|
|
|
[string]$sudo_cmd
|
|
|
|
)
|
|
|
|
|
|
|
|
function do_sudo_win {
|
|
|
|
[CmdletBinding()]param(
|
|
|
|
[string]$sudo_cmd
|
|
|
|
)
|
|
|
|
|
|
|
|
$local:sudo_exec = [string]::Empty
|
|
|
|
if ( (Get-Command scoop -ErrorAction SilentlyContinue) ) {
|
|
|
|
$sudo_exec = $(scoop which gsudo *>&1)
|
2021-01-19 15:17:23 +00:00
|
|
|
if ( "$sudo_exec" -match 'not found' ) {
|
2021-01-15 00:23:51 +00:00
|
|
|
$sudo_exec = $(scoop which sudo *>&1)
|
|
|
|
}
|
2021-01-19 15:17:23 +00:00
|
|
|
if ( "$sudo_exec" -match 'not found' ) { $sudo_exec = [string]::Empty }
|
2021-01-15 00:23:51 +00:00
|
|
|
}
|
|
|
|
if ( $sudo_exec ) {
|
2021-10-12 00:41:46 +00:00
|
|
|
if( [bool]$WhatIfPreference.IsPresent ) {
|
|
|
|
Write-Host "What if: using sudo [$sudo_exec] to run [$sudo_cmd]"
|
|
|
|
} else {
|
|
|
|
& $sudo_exec "$sudoArgs" $sudo_cmd
|
|
|
|
}
|
2021-01-15 00:23:51 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
Write-Error "Didn't find a known sudo command"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( $PSVersionTable.Platform -eq 'Unix' ) {
|
2021-10-12 00:41:46 +00:00
|
|
|
if( [bool]$WhatIfPreference.IsPresent ) {
|
|
|
|
Write-Host "What if: passing encoded command to powershell [$sudo_cmd]"
|
|
|
|
} else {
|
|
|
|
if( -not $sudoArgs ) { $sudoArgs = @( "--preserve-env" ) }
|
|
|
|
/usr/bin/env sudo $sudoArgs $(Get-PowerShellPath) "-noprofile" "-EncodedCommand" $(ConvertTo-Base64 $sudo_cmd)
|
|
|
|
}
|
2021-01-15 00:23:51 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
$local:currentIdenity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
|
|
|
|
if ( $currentIdenity.UserClaims.Value -contains 'S-1-5-32-544' ) {
|
|
|
|
do_sudo_win $sudo_cmd
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
Write-Error "User [$($currentIdenity.Name)]does not have permissions to run as admin."
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( $sudo -and -not $(Test-IsAdmin) ) {
|
|
|
|
$local:tmpOutputFile = $null
|
|
|
|
$local:tmpScriptFile = $null
|
|
|
|
|
|
|
|
$local:sudo_cmd = "$($expr -join ' ')".Trim()
|
|
|
|
if ( $Function ) {
|
|
|
|
$tmpScriptFile = New-TemporaryFile -WhatIf:$false -Confirm:$false
|
|
|
|
$tmpScriptFile = Move-Item $tmpScriptFile.FullName "$($tmpScriptFile.FullName).ps1" -PassThru -WhatIf:$false -Confirm:$false
|
|
|
|
|
|
|
|
$local:tmpScriptContent = Export-FunctionSource $Function
|
|
|
|
$sudo_cmd = "$Function $sudo_cmd"
|
|
|
|
|
|
|
|
$tmpScriptContent | Out-File $tmpScriptFile.FullName -WhatIf:$false
|
|
|
|
$expr = @( ".", $tmpScriptFile.FullName, ";", "`n$Function" ) + $expr
|
|
|
|
}
|
|
|
|
|
|
|
|
$expr = @(
|
|
|
|
"`n`$WhatIfPreference=`$$WhatIfPreference;",
|
|
|
|
"`n`$VerbosePreference='$VerbosePreference';",
|
|
|
|
"`n`$ErrorActionPreference='$ErrorActionPreference';",
|
|
|
|
"`n`$ConfirmPreference='$ConfirmPreference';`n"
|
|
|
|
) + $expr
|
|
|
|
|
|
|
|
if ( $MarshalOutput ) {
|
|
|
|
$tmpOutputFile = New-TemporaryFile -WhatIf:$false -Confirm:$false
|
|
|
|
$expr += @( "| Export-CliXml -Path '$($tmpOutputFile.FullName)'" )
|
|
|
|
}
|
|
|
|
|
|
|
|
$expr += @( ";`n exit `$LastExitCode" )
|
|
|
|
|
|
|
|
## $tmpScriptContent += "$($expr -join ' ')".Trim()
|
|
|
|
Write-Verbose "Performing the following command line via SUDO:`n{$sudo_cmd}"
|
|
|
|
|
|
|
|
$sudo_cmd = "$($expr -join ' ')".Trim()
|
|
|
|
|
|
|
|
do_sudo $sudo_cmd
|
|
|
|
## do_sudo 'Get-Content' $tmpScriptFile.FullName '|' 'Invoke-Expression' '|' 'Export-Clixml' '-Path' $tmpOutputFile.FullName
|
|
|
|
#do_sudo $sudo_cmd
|
|
|
|
|
2021-10-19 01:59:28 +00:00
|
|
|
if ( $tmpScriptFile ) { Remove-Item $tmpScriptFile -Confirm:$false }
|
|
|
|
if ( $tmpOutputFile ) { Import-Clixml $tmpOutputFile; Remove-Item $tmpOutputFile -Confirm:$false }
|
2021-01-15 00:23:51 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
Write-Verbose "Perofrming the following expression in-line:`n{$($expr -join ' ')}"
|
2021-10-12 00:41:46 +00:00
|
|
|
if( [bool]$WhatIfPreference.IsPresent ) {
|
|
|
|
Write-Host "What if: Invoke-ExpressionEx executing [$expr]"
|
|
|
|
} else {
|
|
|
|
Invoke-Expression "$expr"
|
|
|
|
}
|
2021-01-15 00:23:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function Test-IsAdmin {
|
|
|
|
[CmdletBinding(ConfirmImpact = 'None')]
|
|
|
|
[OutputType([bool])]
|
|
|
|
param()
|
|
|
|
|
|
|
|
switch ($true) {
|
|
|
|
$( ($PSVersionTable.PSEdition -eq 'Desktop') -or
|
|
|
|
($PSVersionTable.Platform -eq 'Win32NT')
|
|
|
|
) {
|
|
|
|
# Fastest way on Windows
|
|
|
|
([Security.Principal.WindowsPrincipal](
|
|
|
|
[Security.Principal.WindowsIdentity]::GetCurrent()
|
|
|
|
)).IsInRole(
|
|
|
|
[Security.Principal.WindowsBuiltInRole]'Administrator'
|
|
|
|
)
|
|
|
|
}
|
|
|
|
$( ($PSVersionTable.PSEdition -eq 'Core') -and
|
|
|
|
($PSVersionTable.Platform -eq 'Unix')
|
|
|
|
) {
|
|
|
|
# On macOS and Linux we use ID to figure out if we run elevated (0 means superuser rights)
|
|
|
|
return $((id -u) -eq 0)
|
|
|
|
}
|
|
|
|
default {
|
|
|
|
# Unable to figure it out!
|
|
|
|
Write-Warning -Message 'Unknown'
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function Export-FunctionSource {
|
|
|
|
param(
|
|
|
|
[switch]$NoHeader,
|
|
|
|
[Parameter(Position = 0, ValueFromRemainingArguments = $true)]
|
|
|
|
#[ValidateSet([Functions])]
|
|
|
|
[string[]]$FunctionName
|
|
|
|
)
|
|
|
|
|
|
|
|
$local:src = ""
|
|
|
|
foreach ( $local:func in $FunctionName ) {
|
|
|
|
$local:funcDef = $null
|
|
|
|
foreach( $cmd in (Get-Command -All $func) ) {
|
|
|
|
if( $cmd.CommandType -in @('Function','Filter') ) {
|
|
|
|
$funcDef = $cmd.Definition
|
|
|
|
break
|
|
|
|
} elseif( -$funcDef -and ($cmd.CommandType -in @('Script','ExternalScript')) ) {
|
|
|
|
$funcDef = Get-Content $cmd.Definition
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( -not $funcDef ) {
|
|
|
|
default { throw "Don't know how to handle $func" }
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( -not $NoHeader ) { $src += "`nfunction $func {" }
|
|
|
|
$src += "`n"
|
|
|
|
|
|
|
|
$src += $funcDef
|
|
|
|
if ( -not $NoHeader ) { $src += "`n}" }
|
|
|
|
$src += "`n"
|
|
|
|
}
|
|
|
|
return $src.Trim()
|
|
|
|
}
|
|
|
|
|
|
|
|
# Are we running in Unix or Windows?
|
|
|
|
$global:PathEnvDelimiter = $(if ( $PSVersionTable.Platform -match 'unix' ) { ':' } else { ';' })
|
|
|
|
function Split-PathEnv {
|
|
|
|
param([string]$EnvPath)
|
|
|
|
$EnvPath -split $PathEnvDelimiter
|
|
|
|
}
|
|
|
|
|
|
|
|
# Establish Module Path
|
|
|
|
$global:MyPSModulePath = Split-PathEnv $env:PSModulePath |
|
|
|
|
Where-Object { $_ -match "^$($(Resolve-Path ~) -replace '\\',"\\")" } |
|
|
|
|
Where-Object { Test-Path $_ } |
|
|
|
|
Get-Item | Sort-Object -Property LastWriteTime -Descending |
|
|
|
|
Select-Object -ExpandProperty FullName -First 1
|
|
|
|
|
|
|
|
if ( -not $MyPSModulePath ) {
|
|
|
|
$MyPSModulePath = $(Join-Path $(Join-Path $(Resolve-Path ~) 'powershell') 'Modules')
|
|
|
|
$env:PSModulePath = "$MyPSModulePath$PathEnvDelimiter$env:PSModulePath"
|
|
|
|
}
|
|
|
|
if ( -not (Test-Path $MyPSModulePath) ) {
|
|
|
|
New-Item -ItemType Directory -Path $MyPSModulePath -Force | Out-Null
|
|
|
|
}
|
|
|
|
|
2021-04-23 17:41:59 +00:00
|
|
|
Write-Verbose "`$MyPSModulePath = $(Get-Item $MyPSModulePath | Select-Object -ExpandProperty FullName)"
|
2021-01-15 00:23:51 +00:00
|
|
|
|
|
|
|
# Establish local/personal Script Root and make sure it's in $env:Path
|
2021-04-23 17:41:59 +00:00
|
|
|
if( -not $MyPSScriptRoot ) {
|
|
|
|
if( $My_PSScriptRoot -and -not (Test-Path $My_PSScriptRoot) ) {
|
|
|
|
throw "`$My_PSScriptRoot is defined ($My_PSScriptRoot) but path does NOT exist! stopping"
|
|
|
|
}
|
|
|
|
$local:My_PSScriptRoot = Join-Path (Split-Path -Parent $MyPSModulePath) Scripts
|
|
|
|
Write-Verbose "My_PSScriptRoot = $My_PSScriptRoot"
|
|
|
|
if ( -not (Test-Path $My_PSScriptRoot) ) {
|
|
|
|
New-Item -ItemType Directory -Path $My_PSScriptRoot -Force | Out-Null
|
|
|
|
New-Item -ItemType Directory -Path $(Join-Path $My_PSScriptRoot base) -Force | Out-Null
|
|
|
|
New-Item -ItemType Directory -Path $(Join-Path $(Join-Path $My_PSScriptRoot base) profile.d) -Force | Out-Null
|
|
|
|
}
|
|
|
|
$global:MyPSScriptRoot = $My_PSScriptRoot
|
2021-01-15 00:23:51 +00:00
|
|
|
}
|
|
|
|
|
2021-04-23 17:41:59 +00:00
|
|
|
if( -not (Test-Path $MyPSScriptRoot) ) {
|
|
|
|
throw "`$MyPSScriptRoot ($My_PSScriptRoot) path does NOT exist! stopping!"
|
|
|
|
}
|
2021-01-15 00:23:51 +00:00
|
|
|
|
2021-04-23 17:41:59 +00:00
|
|
|
$local:p1 = Split-PathEnv $env:PATH | Select-Object -Unique
|
|
|
|
Write-Verbose "MyPSScriptRoot = $MyPSScriptRoot"
|
|
|
|
$p2 = @($p1[0], $(Join-Path $MyPSScriptRoot base)) + $($p1 | Select-Object -Skip 1) | Select-Object -Unique
|
|
|
|
$env:PATH = $p2 -join $PathEnvDelimiter
|
|
|
|
Write-Verbose "PATH $(if( $p1.Count -eq $p2.Count ) { "modification" } else { "was modified"} )"
|
2021-11-01 17:21:09 +00:00
|
|
|
Remove-Variable -Name "p1","p2","My_PSScriptRoot" -Confirm:$false
|
2021-04-23 17:41:59 +00:00
|
|
|
}
|
2021-10-19 01:41:15 +00:00
|
|
|
function ProfileCode_cleanup { [CmdletBinding()]param(
|
|
|
|
[switch]$Full
|
|
|
|
)
|
|
|
|
Remove-Item function:ProfileCode* -Confirm:$false
|
|
|
|
if( $Full ) {
|
|
|
|
Remove-Item function:LoadProfileCodeFunctions -Confirm:$false
|
|
|
|
}
|
|
|
|
}
|
2021-01-15 00:23:51 +00:00
|
|
|
|
2021-10-19 01:41:15 +00:00
|
|
|
. ProfileCode_common
|
|
|
|
}
|
2021-04-23 17:41:59 +00:00
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
## _Init Logic - writing starts here
|
|
|
|
#######################################################################
|
|
|
|
function _Init {
|
|
|
|
[CmdletBinding(SupportsShouldProcess)]param(
|
|
|
|
[switch]$WriteInitScript,
|
|
|
|
[string]$CustomInitScriptPath,
|
|
|
|
[switch]$sudo,
|
|
|
|
[switch]$RemoveOnly,
|
|
|
|
[switch]$ShowSkipped,
|
|
|
|
[switch]$Force,
|
|
|
|
[switch]$NoGitAction,
|
|
|
|
[string]$GitURL = 'https://code.lksz.me/lksz/PowerShell_Scripts',
|
|
|
|
[Parameter(DontShow)]
|
|
|
|
[string]$My_PSScriptRoot = $MyPSScriptRoot,
|
|
|
|
[switch]$NoReloadScripts
|
|
|
|
)
|
|
|
|
|
2021-10-19 01:41:15 +00:00
|
|
|
. LoadProfileCodeFunctions
|
|
|
|
|
2021-04-23 17:41:59 +00:00
|
|
|
if ( -not $NoGitAction ) {
|
|
|
|
if ( -not [bool]$(Get-Command git -ErrorAction SilentlyContinue) ) {
|
|
|
|
throw "No git command found, you may either omit run with the -NoGitAction switch or install git and try again."
|
|
|
|
}
|
|
|
|
Push-Location $MyPSScriptRoot
|
|
|
|
if( Test-Path $(Join-Path $MyPSScriptRoot '.git') ) {
|
|
|
|
git pull
|
|
|
|
} elseif ( $PSCmdlet.ShouldProcess("Pull git repo from $GitURL into $MyPSScriptRoot ?") ) {
|
|
|
|
$local:tmpGitDir = New-TemporaryFile
|
2021-10-19 01:59:28 +00:00
|
|
|
Remove-Item $tmpGitDir -Confirm:$false -Force
|
2021-04-23 17:41:59 +00:00
|
|
|
New-Item -Type Directory $tmpGitDir.FullName | Out-Null
|
|
|
|
Write-Verbose "Cloning git repo [$GitURL] into temporary location ('$($tmpGitDir.FullName)')..."
|
|
|
|
$local:GitOutput = "$(& git clone $GitURL $tmpGitDir.FullName --no-checkout)"
|
|
|
|
Write-Verbose $GitOutput
|
|
|
|
Write-Verbose "Moving git repo from temp location to $MyPSScriptRoot . . ."
|
2021-08-23 15:57:46 +00:00
|
|
|
Copy-Item -Force -Recurse (Join-Path $tmpGitDir.FullName .git) ./.git
|
|
|
|
Remove-Item $tmpGitDir.FullName -Recurse -Force -Confirm:$false
|
2021-04-23 17:41:59 +00:00
|
|
|
Write-Verbose "Checking out repo..."
|
|
|
|
$GitOutput = "$(& git checkout --force)"
|
|
|
|
Write-Verbose $GitOutput
|
|
|
|
}
|
|
|
|
Pop-Location
|
|
|
|
Write-Verbose "Git operation done."
|
|
|
|
}
|
|
|
|
|
|
|
|
$local:ProfileSignature = [PSCustomObject]([ordered]@{
|
|
|
|
Begin = '#### SZ Auto Profile Setup - BEGIN ####'
|
|
|
|
End = '#### SZ Auto Profile Setup - END ####'
|
|
|
|
Removed = '#### SZ Auto Profile Setup - ----- ####'
|
|
|
|
Match = '#### SZ Auto Profile Setup'
|
|
|
|
})
|
|
|
|
|
|
|
|
function New-ProfileSetupStatus {
|
|
|
|
param($Name, $Path, $Status, $Exist)
|
|
|
|
return [PSCustomObject]([ordered]@{
|
|
|
|
Name = $Name
|
|
|
|
Path = $Path
|
|
|
|
Status = $Status
|
|
|
|
Exist = $Exist
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
$local:_profiles = @()
|
|
|
|
$local:_profile = $CustomInitScriptPath
|
|
|
|
$local:randomSeed = "####$(Get-Random)####";
|
|
|
|
|
|
|
|
if( $_profile ) {
|
|
|
|
$_profiles += ,$_profile
|
|
|
|
} else {
|
|
|
|
$_profiles = $PROFILE | fl * -Force | Out-String -Stream | ForEach-Object {
|
|
|
|
$local:p = $($_ -split ' : [/A-Z\\]');
|
|
|
|
if ( $p[0] -match 'User' ) {
|
|
|
|
$p[0].Trim()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$_profile = $profile.CurrentUserAllHosts;
|
|
|
|
if ( $sudo -or $(Test-IsAdmin) ) { $_profile = $profile.AllUsersAllHosts }
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( $RemoveOnly -and $ConfirmPreference -eq 'High' -and (-not $PSBoundParameters -or -not $PSBoundParameters.ContainsKey('Confirm')) ) {
|
|
|
|
$script:ConfirmPreference = 'Low'
|
|
|
|
}
|
|
|
|
|
|
|
|
$_profiles | Foreach-Object {
|
|
|
|
$local:p = Invoke-Expression "`$profile.$_"
|
|
|
|
if( -not $p ) { $p = $_ }
|
|
|
|
$local:profileContent = $randomSeed;
|
|
|
|
$local:exists = Test-Path $p
|
|
|
|
$local:userFile = $($_ -match 'CurrentUser')
|
|
|
|
$local:cleanupValue = ''
|
|
|
|
if ( $exists ) {
|
|
|
|
if ( (Get-Content -Path $p | Out-String ) -match $ProfileSignature.Match ) {
|
|
|
|
Write-Verbose "Found code in [$_]'$p', preparing..."
|
|
|
|
$local:gate = $true;
|
|
|
|
$profileContent = Get-Content $p | ForEach-Object {
|
|
|
|
if ( -not $gate ) {
|
|
|
|
if ( $_ -match $ProfileSignature.End ) {
|
|
|
|
$gate = $true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if ( $_ -match $ProfileSignature.Match ) {
|
|
|
|
if ( $_ -match $ProfileSignature.Begin ) {
|
|
|
|
$gate = $false;
|
|
|
|
}
|
|
|
|
$cleanupValue = $ProfileSignature.Removed
|
|
|
|
return $randomSeed;
|
|
|
|
}
|
|
|
|
return $_
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$profileContent += "`n`n$(Get-Content $p -Raw)"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( -not( $profileContent -match $randomSeed ) ) { $profileContent = "$randomSeed`n$profileContent" }
|
|
|
|
|
|
|
|
$local:insertProfileCode = $false;
|
|
|
|
if ( ($p -eq $_profile) -and -not $RemoveOnly ) {
|
|
|
|
$insertProfileCode = $true
|
|
|
|
Write-Verbose "Inserting ProfileCode into $($_)..."
|
|
|
|
$cleanupValue = $((@(
|
|
|
|
'',
|
|
|
|
$ProfileSignature.Begin,
|
|
|
|
'',
|
|
|
|
$(Export-FunctionSource -NoHeader ProfileCode_pre_common),
|
|
|
|
'',
|
|
|
|
'',
|
|
|
|
$(Export-FunctionSource -NoHeader ProfileCode_common),
|
|
|
|
'',
|
|
|
|
'',
|
|
|
|
$(Export-FunctionSource -NoHeader ProfileCode_post_common),
|
|
|
|
'',
|
|
|
|
$ProfileSignature.End
|
|
|
|
) -join "`n" ).Trim().Replace(('$' + '_'), ('$$' + '_')))
|
|
|
|
}
|
|
|
|
|
|
|
|
$profileContent = $($profileContent -replace $randomSeed, $cleanupValue).Trim()
|
|
|
|
|
|
|
|
$local:shouldSudo = $sudo -and -not $userFile
|
|
|
|
$local:status = 'Skipped'
|
|
|
|
if ( $VerbosePreference -eq 'Continue' ) { $ShowSkipped = $true }
|
|
|
|
# Test if new profile Content will be empty
|
|
|
|
if ( -not ([string]::IsNullOrWhiteSpace($profileContent)) ) {
|
|
|
|
$status = "Need $(if($insertProfileCode){if($exists){'Setup'}else{'Init'}}else{'Cleanup'})"
|
|
|
|
if ( $sudo -or $userFile ) {
|
|
|
|
Write-Verbose "Writing content to $($_)..."
|
|
|
|
$local:tmpOutput = New-TemporaryFile -WhatIf:$false -Confirm:$false
|
|
|
|
$profileContent | Out-File $tmpOutput.FullName -WhatIf:$false -Confirm:$false
|
|
|
|
if ( $shouldSudo -and $( $PSVersionTable.Platform -eq 'Unix' ) ) {
|
|
|
|
# Make sure the file has the right permissions on a Unix machine
|
|
|
|
Invoke-ExpressionEx -sudo:$shouldSudo chmod 'a+r' $tmpOutput.FullName
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
$local:errMsg = $(Invoke-ExpressionEx -Confirm:$false -sudo:$shouldSudo @"
|
|
|
|
if( -not (Test-Path $(Split-Path -Parent $p)) ) { New-Item -Type Directory "$(Split-Path -Parent $p)" -Force };
|
|
|
|
`$null = Copy-Item "$($tmpOutput.FullName)" "$p" -Force:`$$Force -ErrorAction Stop;
|
|
|
|
Remove-Item "$($tmpOutput.FullName)" -Force:`$$Force -ErrorAction SilentlyContinue
|
|
|
|
"@ 2>&1)
|
|
|
|
if ( $errMsg ) {
|
|
|
|
Write-Error "$errMsg"
|
|
|
|
$status = $status -replace 'Need ', 'Failed '
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$status = $status -replace 'Need ', ''
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch {
|
|
|
|
Write-Error "Writing $p failed!"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
2021-06-29 13:43:27 +00:00
|
|
|
#$status = $status -replace "Need ", '' -replace '^ ?','Need '
|
2021-04-23 17:41:59 +00:00
|
|
|
Write-Error "Cannot write into [$_]'$p'! Please re-run with sudo."
|
|
|
|
}
|
|
|
|
}
|
|
|
|
elseif ( ($Force -or $RemoveOnly) -and $exists ) {
|
|
|
|
$status = 'Need Removal'
|
|
|
|
if ( $sudo -or $userFile ) {
|
|
|
|
Write-Verbose "Removing [$_]'$p'..."
|
|
|
|
try {
|
|
|
|
Invoke-ExpressionEx -sudo:$shouldSudo Remove-Item $p
|
|
|
|
if ( -not (Test-Path $p) ) { $status = 'Removed' }
|
|
|
|
}
|
|
|
|
catch {
|
|
|
|
Write-Error "Removal of $p failed!"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
Write-Error "Cannot remove [$_]'$p'! Please re-run with sudo."
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( $status -ne 'Skipped' -or $ShowSkipped ) {
|
|
|
|
if ( $shouldSudo -and $status -ne 'Skipped' ) { $status = "$status via sudo" }
|
|
|
|
New-ProfileSetupStatus -Name $_ -Path $p -Status $status -Exist $(Test-Path $p)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Get-Item function:_Init | Remove-Item -Confirm:$false
|
2021-10-19 01:41:15 +00:00
|
|
|
. ProfileCode_cleanup -Full
|
2021-01-15 00:23:51 +00:00
|
|
|
}
|
2021-04-23 17:41:59 +00:00
|
|
|
|
2021-10-19 01:41:15 +00:00
|
|
|
. LoadProfileCodeFunctions
|
|
|
|
|
2021-04-23 17:41:59 +00:00
|
|
|
if( -not $MyPSScriptRoot ) { throw '$MyPSScriptRoot does NOT exist!' }
|
|
|
|
|
|
|
|
if( $WriteInitScript ) {
|
|
|
|
_Init @PSBoundParameters
|
|
|
|
}
|
|
|
|
|
2021-10-19 01:41:15 +00:00
|
|
|
. ProfileCode_cleanup
|
2021-04-23 17:41:59 +00:00
|
|
|
|
|
|
|
if( $NoReloadScripts ) { return }
|
|
|
|
|
|
|
|
Get-Command Reload-MyScripts -ErrorAction SilentlyContinue |
|
|
|
|
ForEach-Object {
|
|
|
|
Write-Verbose "Reload-MyScripts"
|
|
|
|
. $_.Name -Confirm:$false
|
|
|
|
}
|