diff --git a/Aliases/dcedit.ps1 b/Aliases/dcedit.ps1 new file mode 100644 index 0000000..a5533c7 --- /dev/null +++ b/Aliases/dcedit.ps1 @@ -0,0 +1 @@ +Edit-DockerCompose diff --git a/Aliases/dco.ps1 b/Aliases/dco.ps1 new file mode 100644 index 0000000..e41f756 --- /dev/null +++ b/Aliases/dco.ps1 @@ -0,0 +1 @@ +docker-compose diff --git a/Aliases/dps.ps1 b/Aliases/dps.ps1 new file mode 100644 index 0000000..640b880 --- /dev/null +++ b/Aliases/dps.ps1 @@ -0,0 +1 @@ +Get-DockerProcess diff --git a/Aliases/edit b/Aliases/edit new file mode 100644 index 0000000..e099b51 --- /dev/null +++ b/Aliases/edit @@ -0,0 +1 @@ +Edit-TextFile diff --git a/Aliases/l.ps1 b/Aliases/l.ps1 new file mode 100644 index 0000000..9e2740c --- /dev/null +++ b/Aliases/l.ps1 @@ -0,0 +1 @@ +ls diff --git a/Aliases/ll.ps1 b/Aliases/ll.ps1 new file mode 100644 index 0000000..9e2740c --- /dev/null +++ b/Aliases/ll.ps1 @@ -0,0 +1 @@ +ls diff --git a/Aliases/sz-update.ps1 b/Aliases/sz-update.ps1 new file mode 100644 index 0000000..c680027 --- /dev/null +++ b/Aliases/sz-update.ps1 @@ -0,0 +1 @@ +Update-OSz diff --git a/Aliases/vi b/Aliases/vi new file mode 100644 index 0000000..e099b51 --- /dev/null +++ b/Aliases/vi @@ -0,0 +1 @@ +Edit-TextFile diff --git a/Aliases/vidc.ps1 b/Aliases/vidc.ps1 new file mode 100644 index 0000000..a5533c7 --- /dev/null +++ b/Aliases/vidc.ps1 @@ -0,0 +1 @@ +Edit-DockerCompose diff --git a/Aliases/vim b/Aliases/vim new file mode 100644 index 0000000..e099b51 --- /dev/null +++ b/Aliases/vim @@ -0,0 +1 @@ +Edit-TextFile diff --git a/ConvertFrom-Base64.ps1 b/ConvertFrom-Base64.ps1 new file mode 100644 index 0000000..4dbbdeb --- /dev/null +++ b/ConvertFrom-Base64.ps1 @@ -0,0 +1,2 @@ +param([string]$Base64String) + return [System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String($Base64String)) diff --git a/Edit-DockerCompose.ps1 b/Edit-DockerCompose.ps1 new file mode 100644 index 0000000..9d491f4 --- /dev/null +++ b/Edit-DockerCompose.ps1 @@ -0,0 +1,14 @@ +[CmdletBinding(SupportsShouldProcess)]param([string[]]$ProjectPath=@($PWD),[switch]$Force) + +$local:editCandidates = @('docker-compose.yml','.base.docker-compose.yml') +$local:editFiles = @() +foreach( $local:fileName in $EditCandidates ) { + foreach( $local:path in $ProjectPath ) { + $local:testPath = Join-Path $path $fileName + if( $Force -or $(Test-Path $testPath) ) { $editFiles += $testPath } + } +} + +Edit-TextFile $editFiles + +$editFiles | Select-Object -First 1 | ForEach-Object { docker-compose --file $(Resolve-Path $_) config -q } diff --git a/Edit-MyConfig.ps1 b/Edit-MyConfig.ps1 new file mode 100644 index 0000000..1204eef --- /dev/null +++ b/Edit-MyConfig.ps1 @@ -0,0 +1,24 @@ +[CmdletBinding(SupportsShouldProcess)]param( + [Parameter(Position = 0, ValueFromRemainingArguments)] + [ArgumentCompleter({ param ( + $commandName, + $parameterName, + $wordToComplete, + $commandAst, + $fakeBoundParameters + ) + [MyConfig]::_GetValidValues($wordToComplete,$true) | Sort-Object + })] + [string[]]$ConfigName, + [switch]$Force, + [switch]$sudo +) +if( -not $ConfigName ) { + ([MyConfig]::_GetValidValues('',$true)) | Sort-Object + return +} +$local:ScriptPaths = [MyConfig]::GetConfigPaths($ConfigName,$Force) + +Edit-TextFile -sudo:$sudo $ScriptPaths + +$null = [MyConfig]::_GetValidValues('', $true) diff --git a/Edit-MyScript.ps1 b/Edit-MyScript.ps1 index 1cc37a9..50cf3b0 100644 --- a/Edit-MyScript.ps1 +++ b/Edit-MyScript.ps1 @@ -9,6 +9,16 @@ [FunctionName]::_GetValidValues($wordToComplete,$true) })] [string[]]$ImportFunction, + [ArgumentCompleter({ param ( + $commandName, + $parameterName, + $wordToComplete, + $commandAst, + $fakeBoundParameters + ) + [SystemName]::_GetValidValues($wordToComplete,$false,$true) + })] + [string]$System, [switch]$ForceImport, [Parameter(Position = 0, ValueFromRemainingArguments = $true)] [ArgumentCompleter({ param ( @@ -18,16 +28,24 @@ $commandAst, $fakeBoundParameters ) - [MyScript]::_GetValidValues($wordToComplete,$true) + $local:possibleValues = [MyScript]::_GetValidValues($wordToComplete,$true) + if( $fakeBoundParameters.ContainsKey("System") ) { + $possibleValues = $possibleValues | Where-Object { $_ -match "^sys\.$($fakeBoundParameters.System)" } | ForEach-Object { $_ -replace "^sys\.$($fakeBoundParameters.System).",'' } + } + $possibleValues })] [string[]]$ScriptName ) +$local:EditRootPath=$MyPSScriptRoot +if( $System ) { + $EditRootPath = Join-Path $EditRootPath "sys.$System" +} $local:ScriptPaths = @() foreach( $local:p in $ImportFunction ) { $local:f = Get-Command $p -Type Function if( $f ) { - $local:sp = Join-Path $MyPSScriptRoot "$p`.ps1" + $local:sp = Join-Path $EditRootPath "$p`.ps1" if( $ForceImport -or -not (Test-Path $sp) ) { Export-FunctionSource $p -NoHeader > $sp } elseif ( -not $ForceImport ) { @@ -37,15 +55,29 @@ foreach( $local:p in $ImportFunction ) { } } foreach( $local:p in $ScriptName ) { - $local:sp = Join-Path $MyPSScriptRoot "$p`.ps1" + $local:sp = Join-Path $EditRootPath "$p`.ps1" $ScriptPaths += $sp } if( -not $ScriptPaths ) { - $ScriptPaths += $MyPSScriptRoot + $ScriptPaths += $EditRootPath } +foreach( $local:p in $ScriptPaths ) { + $local:parentPath = Split-Path -Parent $p; + if( -not (Test-Path $p) -and -not (Test-Path $parentPath) ) { + Write-Verbose "Creating missing path $parentPath..." + New-Item -Type Directory $parentPath + } +} + +$local:sw = [System.Diagnostics.Stopwatch]::StartNew(); Edit-TextFile $ScriptPaths +$sw.Stop(); + +if( $sw.Elapsed.TotalSeconds -lt 1 ) { + $null = Read-Host "Waiting before refreshing. Press when you're done editing ( don't forget to save ;) )..." +} Get-Command Reload-MyScripts -ErrorAction SilentlyContinue | ForEach-Object { . $_.Definition } diff --git a/Get-DockerProcess.ps1 b/Get-DockerProcess.ps1 new file mode 100644 index 0000000..b6f1aa3 --- /dev/null +++ b/Get-DockerProcess.ps1 @@ -0,0 +1,24 @@ +#[CmdletBinding(SupportsShouldProcess)]param( +[CmdletBinding()]param([string[]]$MatchName,[string[]]$OrderBy,[switch]$PassThru,[string[]]$MatchAny) + +$local:result = $(docker ps --format='{{ .Image }}\t{{ .Names }}\t{{ .Status }}\t{{ .Ports }}' | + ForEach-Object { + $local:l = $_ -split '\t'; + [PSCustomObject]([ordered]@{Image=$l[0];Name=$l[1];Status=$l[2];Ports=$l[3] -replace ', ',"`n"}) + } ) | Sort-Object Name + +if( $MatchName ) { + $result = $result | Where-Object Name -match $($MatchName -join '|') +} + +if( $MatchAny ) { + $result = $result | Where-Object { $_ | Out-String | Where-Object { $_ -match $($MatchAny -join '|') } } +} + +if( $OrderBy ) { + $result = $result | Sort-Object $OrderBy +} + +if( $PassThru ) { return $result } +$result | Format-Table -Wrap + diff --git a/Get-MyAliases.ps1 b/Get-MyAliases.ps1 deleted file mode 100644 index ddcbcef..0000000 --- a/Get-MyAliases.ps1 +++ /dev/null @@ -1,26 +0,0 @@ -[CmdletBinding(SupportsShouldProcess)]param() - -$local:allAliases = @() - -$MyAliasScope = 0 -$local:_scope = 0 -$local:_done = $false -do { - try { - $local:newAliases += Get-Alias -Scope $_scope | - Where-Object { - ($_.Definition -match "^$MyPSScriptRoot") -or ($_.Description -match '#MyAlias') - } - if( $newAliases ) { - $allAliases += $newAliases - $MyAliasScope = $_scope; - Write-Verbose "`$MyAliasScope is now set to $MyAliasScope" - } - } catch { - Write-Verbose "catch: $($_.Exception.Message)" - $_done = $_.Exception.Message -match 'The scope .* exceeds' - } - $_scope += 1 -} until ( $_done ) - -$allAliases diff --git a/Get-Path.ps1 b/Get-Path.ps1 new file mode 100644 index 0000000..7dccf1f --- /dev/null +++ b/Get-Path.ps1 @@ -0,0 +1,8 @@ +[CmdletBinding()]param([string]$Path) + +try { + get-item $Path -Force -ErrorAction Stop | + Select-Object -ExpandProperty FullName +} catch { + $_.targetObject +} diff --git a/Invoke-Sudo.ps1 b/Invoke-Sudo.ps1 new file mode 100644 index 0000000..c8816d3 --- /dev/null +++ b/Invoke-Sudo.ps1 @@ -0,0 +1,6 @@ +[CmdletBinding(SupportsShouldProcess)]param( + [Parameter(Mandatory = $true,Position = 0, ValueFromRemainingArguments = $true)] + $expr +) + +. Invoke-ExpressionEx -sudo $expr diff --git a/README.md b/README.md index a6b3396..47dd6b2 100644 --- a/README.md +++ b/README.md @@ -6,41 +6,21 @@ The development of these is documented in my blog: https://blog.lksz.me They are provided 'as is' for your review and for your reuse. -There is a [blog post](https://blog.lksz.me/keeping-track-of-everything/#-mypsscriptroot) about how to clone this repo and use it as your own. - -The scripts all [assume](https://blog.lksz.me/functions-or-scripts/#myprofilecode) the code below is part of one of your $PROFILE files. -The code establishes the following variables: -* `$PathEnvDelimiter` - Linux/Unix it's `:`, while in Windows it's `;` -* `$MyPSModulePath` - Location to place personal Modules -* `$MyPSScriptRoot` - Location of personal Scripts. - -The code also makes sure `$MyPSScriptRoot` is in the `$env:PATH` environment vairable, and finally it calls [`Reload-MyAliases`](https://blog.lksz.me/a-case-of-sensitivity/#myaliases) if it exists. - +This envrionment can be installed using one the following options: +### The Short, yet safer way +```PowerShell +iwr https://lksz.me/pwsz | iex ``` -$global:PathEnvDelimiter = $(if( $PSVersionTable.Platform -match 'unix' ) {':'} else {';'}) -function Split-PathEnv { -param([string]$EnvPath) - $EnvPath -split $PathEnvDelimiter -} -$global:MyPSModulePath = Split-PathEnv $env:PSModulePath | Where-Object { $_ -match "^$(Resolve-Path ~)" } +This sets up the `$PROFILE` file, and initilizes the default dir `$MyPSScriptRoot` with a git clone of this repo. +The `https://lksz.me/pwsz` actually points to the [`Setup-Profile.ps1`](Setup-Profile.ps1) script, which means, that after you have the `Scripts` directory setup, you can call `Setup-Profile` to update the `$PROFILE` after the `Setup-Profile.ps1` has been modified (or updated via `git pull`). -if( -not $MyPSModulePath ) { - $MyPSModulePath = Resolve-Path ~/powershell/Modules - if( -not (Test-Path $MyPSModulePath) ) { - New-Item -ItemType Directory -Path $MyPSModulePath -Force | Out-Null - } - $env:PSModulePath = "$MyPSModulePath$PathEnvDelimiter$env:PSModulePath" -} - -$local:p = Split-PathEnv $env:PATH -$global:MyPSScriptRoot = Join-Path (Split-Path -Parent $MyPSModulePath) Scripts -if( -not (Test-Path $MyPSScriptRoot) ) { - New-Item -ItemType Directory -Path $MyPSScriptRoot -Force | Out-Null -} - -$p = @($p[0], $MyPSScriptRoot) + $($p | Select-Object -Skip 1) -$env:PATH = $p -join $PathEnvDelimiter - -Get-Command Reload-MyScripts -ErrorAction SilentlyContinue | ForEach-Object { . $_.Name } +### The Short, but with control option +```PowerShell +$sfw=1; iwr https://lksz.me/pwsz | iex; _setup [-sudo] [-Force] [-NoGitClone] [-GitURL ] [-WhatIf] [-Confirm] [] ``` + +The key here is `$sfw=1`, which can be substitued with the more verbose `$SetupFromWeb=1`, this let's the [`Setup-Profile`](Setup-Profile.ps1) script know to just load it's content, but allow you to manually call it's internal function via `_setup` + +### The 'I don't trust one liners, what's going on ?!?' option +You can always clone the git repo first, and only then run the [`Setup-Profile.ps1`](Setup-Profile.ps1) script. \ No newline at end of file diff --git a/Reload-MyScripts.ps1 b/Reload-MyScripts.ps1 index fd0aca3..c421da8 100644 --- a/Reload-MyScripts.ps1 +++ b/Reload-MyScripts.ps1 @@ -1,21 +1,51 @@ [CmdletBinding(SupportsShouldProcess)]param() -$local:myAliases = [ordered]@{} -$myAliases.sudo = 'Invoke-Sudo' -$myAliases.vi = 'Edit-TextFile' -$myAliases.vim = 'Edit-TextFile' -$myAliases.nvim = 'Edit-TextFile' -$myAliases.nvim = 'Edit-TextFile' -$myAliases.l = 'ls.ps1' -$myAliases.ll = 'ls.ps1' +try { Get-Alias Get-MyAliases -ErrorAction Stop | ForEach-Object { Remove-Item "Alias:$($_.Name)" } } catch {} +function Get-MyAliases { +[CmdletBinding(SupportsShouldProcess)]param([switch]$ScriptsOnly) -####################################################################### + $local:allAliases = @() + + $MyAliasScope = 0 + $local:_scope = 0 + $local:_done = $false + do { + try { + $local:newAliases += Get-Alias -Scope $_scope | + Where-Object { + ($_.Definition -match "^$MyPSScriptRoot") -or (-not $ScriptsOnly -and ($_.Description -match '#MyAlias')) + } + if( $newAliases ) { + $allAliases += $newAliases + $MyAliasScope = $_scope; + Write-Verbose "`$MyAliasScope is now set to $MyAliasScope" + } + } catch { + Write-Verbose "catch: $($_.Exception.Message)" + $_done = $_.Exception.Message -match 'The scope .* exceeds' + } + $_scope += 1 + } until ( $_done ) + + $allAliases +} + +function getScriptName{param([string]$FullPath) + $FullPath -replace '\.ps1$','' -replace "^$([regex]::Escape($MyPSScriptRoot)).",'' +} + +$local:myAliases = [ordered]@{} +if( Test-Path $(Join-Path $MyPSScriptRoot Aliases) ) { + Get-ChildItem $(Join-Path $MyPSScriptRoot Aliases) | ForEach-Object { + $myAliases[$_.BaseName] = Get-Content $_.FullName + } +} $local:IsVerbose = [bool]($PSBoundParameters['Verbose']) -$local:MyAliasScope = 1 +$script:MyAliasScope = 0 -$local:oldAliases = . Get-MyAliases +$local:oldAliases = Get-MyAliases $oldAliases = Get-Alias -Scope $MyAliasScope | Where-Object Name -in $($oldAliases.Name + $myAliases.Keys) @@ -29,14 +59,30 @@ if( Get-Command Remove-Alias -ErrorAction SilentlyContinue ) { $oldAliases | ForEach-Object { Remove-Item "Alias:$($_.Name)" } } -Get-ChildItem (Join-Path $MyPSScriptRoot '*.ps1') | - ForEach-Object { +if( $(. Get-ScopeDepth) -gt 0 ) { Write-Host -ForegroundColor Red "Try sourcing Reload-MyScripts instead of just running it" } +Get-ChildItem $(Join-Path $MyPSScriptRoot profile.d) -Filter '*.ps1' | ForEach-Object { + Write-Verbose "Loading $(getScriptName $_.FullName)..."; + ". '$($_.FullName)';" + } | Invoke-Expression + +$local:CommandsToAlias = ( + @( $MyPSScriptRoot ) + $( + [SystemName]::_GetValidValues("",$true,$true) | ForEach-Object { + Join-Path $MyPSScriptRoot "sys.$_" + } + )) | ForEach-Object { + if( Test-Path $_ ) { + Get-ChildItem (Join-Path $_ '*.ps1') | Where-Object Name -notmatch '\.inc\.ps1$' + } + } + +$CommandsToAlias | ForEach-Object { + Write-Verbose "Creating alias for $(getScriptName $_.FullName) Script..." Set-Alias $($_.BaseName) $_.FullName -Scope $MyAliasScope } foreach( $local:alias in $myAliases.Keys ) { + Write-Verbose "Adding $($alias) alias..." Set-Alias -Name $alias -Value $myAliases[$alias] -Description '#MyAlias' -Scope $MyAliasScope } -if( $(. Get-ScopeDepth) -gt 0 ) { Write-Host -ForegroundColor Red "Try sourcing Reload-MyScripts instead of just running it" } -Get-ChildItem $(Join-Path $MyPSScriptRoot profile.d) -Filter '*.ps1' | ForEach-Object { ". '$($_.FullName)';" } | Invoke-Expression diff --git a/Setup-Profile.ps1 b/Setup-Profile.ps1 index 0173767..b4276dc 100644 --- a/Setup-Profile.ps1 +++ b/Setup-Profile.ps1 @@ -3,10 +3,10 @@ [switch]$RemoveOnly, [switch]$ShowSkipped, [switch]$Force, - [switch]$GitClone, + [switch]$NoGitAction, [string]$GitURL = 'https://code.lksz.me/lksz/PowerShell_Scripts', [Parameter(DontShow)] - [string]$MyPSScriptRoot = $MyPSScriptRoot + [string]$My_PSScriptRoot = $MyPSScriptRoot ) function _Setup { @@ -15,10 +15,10 @@ function _Setup { [switch]$RemoveOnly, [switch]$ShowSkipped, [switch]$Force, - [switch]$GitClone, + [switch]$NoGitAction, [string]$GitURL = 'https://code.lksz.me/lksz/PowerShell_Scripts', [Parameter(DontShow)] - [string]$MyPSScriptRoot = $MyPSScriptRoot) + [string]$My_PSScriptRoot = $MyPSScriptRoot) ####################################################################### @@ -40,12 +40,17 @@ Get-Command Reload-MyScripts -ErrorAction SilentlyContinue | ForEach-Object { . ## _Setup Logic starts here ####################################################################### - if ( $GitClone -and -not (Test-Path $(Join-Path $MyPSScriptRoot '.git')) ) { + . ProfileCode_common + if( -not $MyPSScriptRoot ) { throw '$MyPSScriptRoot does NOT exist!' } + + if ( -not $NoGitAction ) { if ( -not [bool]$(Get-Command git -ErrorAction SilentlyContinue) ) { - throw "No git command found, you may either omit the -GitClone switch or install git and try again." + throw "No git command found, you may either omit run with the -NoGitAction switch or install git and try again." } - if ( $PSCmdlet.ShouldProcess("Pull git repo from $GitURL into $MyPSScriptRoot ?") ) { - Push-Location $MyPSScriptRoot + 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 Remove-Item $tmpGitDir New-Item -Type Directory $tmpGitDir.FullName | Out-Null @@ -53,14 +58,14 @@ Get-Command Reload-MyScripts -ErrorAction SilentlyContinue | ForEach-Object { . $local:GitOutput = "$(& git clone $GitURL $tmpGitDir.FullName --no-checkout)" Write-Verbose $GitOutput Write-Verbose "Moving git repo from temp location to $MyPSScriptRoot . . ." - Move-Item (Join-Path $tmpGitDir.FullName .git) ./.git + Copy-Item -Recurse (Join-Path $tmpGitDir.FullName .git) ./.git Remove-Item $tmpGitDir.FullName Write-Verbose "Checking out repo..." $GitOutput = "$(& git checkout --force)" Write-Verbose $GitOutput - Pop-Location - Write-Verbose "-GitClone step done." } + Pop-Location + Write-Verbose "Git operation done." } $local:ProfileSignature = [PSCustomObject]([ordered]@{ @@ -166,7 +171,11 @@ Get-Command Reload-MyScripts -ErrorAction SilentlyContinue | ForEach-Object { . Invoke-ExpressionEx -sudo:$shouldSudo chmod 'a+r' $tmpOutput.FullName } try { - $local:errMsg = $(Invoke-ExpressionEx -sudo:$shouldSudo "Move-Item $($tmpOutput.FullName) $p -Force:`$$Force -ErrorAction Stop | Out-Null" 2>&1) + $local:errMsg = $(Invoke-ExpressionEx -sudo:$shouldSudo @" + if( -not (Test-Path $(Split-Path -Parent $p)) ) { New-Item -Type Directory $(Split-Path -Parent $p) -Force }; + Copy-Item $($tmpOutput.FullName) $p -Force:`$$Force -ErrorAction Stop | Out-Null; + Remove-Item $($tmpOutput.FullName) -Force:`$$Force -ErrorAction Stop +"@ 2>&1) if ( $errMsg ) { Write-Error "$errMsg" $status = $status -replace 'Need ', 'Failed ' @@ -380,10 +389,10 @@ param([string]$EnvPath) # 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 + 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') @@ -397,25 +406,23 @@ Write-Verbose $(Get-Item $MyPSModulePath | Select-Object -ExpandProperty FullNam # Establish local/personal Script Root and make sure it's in $env:Path $local:p = Split-PathEnv $env:PATH -$MyPSScriptRoot = Join-Path (Split-Path -Parent $MyPSModulePath) Scripts -Write-Verbose "MyPSScriptRoot = $MyPSScriptRoot" -if ( -not (Test-Path $MyPSScriptRoot) ) { - New-Item -ItemType Directory -Path $MyPSScriptRoot -Force | Out-Null - New-Item -ItemType Directory -Path $MyPSScriptRoot/profile.d -Force | Out-Null +$local:My_PSScriptRoot = Join-Path (Split-Path -Parent $MyPSModulePath) Scripts +Write-Verbose "MyPSScriptRoot = $My_PSScriptRoot" +if ( -not (Test-Path $My_PSScriptRoot) ) { + New-Item -ItemType Directory -Path $My_PSScriptRoot -Force | Out-Null + New-Item -ItemType Directory -Path $My_PSScriptRoot/profile.d -Force | Out-Null } -$global:MyPSScriptRoot = $MyPSScriptRoot +$global:MyPSScriptRoot = $My_PSScriptRoot $p = @($p[0], $MyPSScriptRoot) + $($p | Select-Object -Skip 1) $env:PATH = $p -join $PathEnvDelimiter } -if ( -not $MyPSScriptRoot -or (Test-Path function:Test-IsAdmin, function:ConvertTo-Base64, function:Invoke-ExpressionEx, function:Get-PowerShellPath, function:Export-FunctionSource | Where-Object { -not $_ } | Measure-Object | Select-Object -ExpandProperty Count) ) { - Write-Verbose "Calling ProfileCode inline..." - . ProfileCode_common -} +$SetupFromWeb = [bool]$(@( $SetupFromWeb, $sfw, $LoadCode ) | Where-Object { $_ }) if ( -not $SetupFromWeb ) { _setup @PSBoundParameters Get-Item function:_setup | Remove-Item + Get-Command Reload-MyScripts -ErrorAction SilentlyContinue | ForEach-Object { . $_.Name } } Remove-Variable SetupFromWeb -ErrorAction SilentlyContinue diff --git a/Stop-ProcessTree.ps1 b/Stop-ProcessTree.ps1 new file mode 100644 index 0000000..9e838e0 --- /dev/null +++ b/Stop-ProcessTree.ps1 @@ -0,0 +1,13 @@ +[cmdletbinding()]param([string]$ProcessName) + $local:new_KillPIDs = @() + (Get-Process -name $processName | Select-Object -ExpandProperty ID) + $local:KillPIDs = @() + Do { + $KillPIDs += $new_KillPIDs | Where-Object { $_ -notin $KillPIDs } + Write-Verbose "Again" + Write-Verbose $new_KillPIDs -join ", " + $new_KillPIDs = $new_KillPIDs | ForEach-Object { Get-CimInstance -ClassName Win32_Process -Filter "ParentProcessId = $_" } | Select-Object -ExpandProperty ProcessId + } Until ( -not $new_KillPIDs ) + + Write-Verbose "Done" + + start-process powershell -ArgumentList "-command","Stop-Process -Force -Id @($($KillPIDs -join '', ''))" -WindowStyle Minimized diff --git a/dcc.ps1 b/dcc.ps1 new file mode 100644 index 0000000..6154b3a --- /dev/null +++ b/dcc.ps1 @@ -0,0 +1,3 @@ +[CmdletBinding(SupportsShouldProcess)]param([string[]]$ProjectPath=@($PWD)) + +$ProjectPath | ForEach-Object { docker-compose --file $(Resolve-Path $(Join-Path $_ docker-compose.yml)) config | less } diff --git a/dcdown.ps1 b/dcdown.ps1 new file mode 100644 index 0000000..a7cd9c5 --- /dev/null +++ b/dcdown.ps1 @@ -0,0 +1 @@ +docker-compose down --timeout=3 --volumes --remove-orphans "$args" diff --git a/dcl.ps1 b/dcl.ps1 new file mode 100644 index 0000000..d41ca60 --- /dev/null +++ b/dcl.ps1 @@ -0,0 +1 @@ +docker-compose logs --tail=40 --follow "$args" diff --git a/dcll.ps1 b/dcll.ps1 new file mode 100644 index 0000000..a5ffc0d --- /dev/null +++ b/dcll.ps1 @@ -0,0 +1 @@ +docker-compose logs "$args" diff --git a/dcr.ps1 b/dcr.ps1 new file mode 100644 index 0000000..6406f9e --- /dev/null +++ b/dcr.ps1 @@ -0,0 +1 @@ +docker-compose run --rm "$args" diff --git a/dcre.ps1 b/dcre.ps1 new file mode 100644 index 0000000..f0fc796 --- /dev/null +++ b/dcre.ps1 @@ -0,0 +1 @@ +docker-compose restart "$args" diff --git a/dcreup.ps1 b/dcreup.ps1 new file mode 100644 index 0000000..052c0d5 --- /dev/null +++ b/dcreup.ps1 @@ -0,0 +1,11 @@ +#[CmdletBinding(SupportsShouldProcess)]param() + +$local:dcParams = [string]::Empty +if( $args ) { + $dcParams = $args | ForEach-Object { + if( $_ -match "(?:^'[^']+'$)|(?:^`"[^`"]+`"$)|(?:^[^\s]+$)" ) { $_ } + else { "'$($_.Replace( "'", "''" ))'" } + } +} +docker-compose up -d --force-recreate --remove-orphans $dcParams && docker-compose logs --follow --tail 10 $dcParams + diff --git a/dcup.ps1 b/dcup.ps1 new file mode 100644 index 0000000..5ab64b0 --- /dev/null +++ b/dcup.ps1 @@ -0,0 +1,10 @@ +#[CmdletBinding(SupportsShouldProcess)]param() + +$local:dcParams = [string]::Empty +if( $args ) { + $dcParams = $args | ForEach-Object { + if( $_ -match "(?:^'[^']+'$)|(?:^`"[^`"]+`"$)|(?:^[^\s]+$)" ) { $_ } + else { "'$($_.Replace( "'", "''" ))'" } + } +} +docker-compose up -d --remove-orphans $dcParams && docker-compose logs --follow --tail 10 $dcParams diff --git a/dcx.ps1 b/dcx.ps1 new file mode 100644 index 0000000..130dda9 --- /dev/null +++ b/dcx.ps1 @@ -0,0 +1 @@ +docker-compose exec "$args" diff --git a/di.ps1 b/di.ps1 new file mode 100644 index 0000000..97c8027 --- /dev/null +++ b/di.ps1 @@ -0,0 +1 @@ +docker inspect "$args" diff --git a/dl.ps1 b/dl.ps1 new file mode 100644 index 0000000..6d4edec --- /dev/null +++ b/dl.ps1 @@ -0,0 +1 @@ +docker logs --tail=40 --follow "$args" diff --git a/dll.ps1 b/dll.ps1 new file mode 100644 index 0000000..cadf8c1 --- /dev/null +++ b/dll.ps1 @@ -0,0 +1 @@ +docker logs "$args" diff --git a/dx.ps1 b/dx.ps1 new file mode 100644 index 0000000..d69452c --- /dev/null +++ b/dx.ps1 @@ -0,0 +1 @@ +docker exec "$args" diff --git a/profile.d/FromPowerShellCookbook.ps1 b/profile.d/FromPowerShellCookbook.ps1 new file mode 100644 index 0000000..75018ca --- /dev/null +++ b/profile.d/FromPowerShellCookbook.ps1 @@ -0,0 +1,21 @@ +# PowerShell Cookbook has a lot of code there, I'm only interested in +# the Add-ObjectCollector which adds an overloaded Out-Default version, +# which stores a history of output objects. +# One major problem with loading this from the module, is that when the +# module is removed the shell BREAKS. +# +# The code below, makes sure the module is removed, and then imports +# only the Add-ObjectCollector code from it. +# All I really want is the Out-Default function created by +# Add-ObjectCollector, and so, I'll also remove the function once done. + +if( Get-Module PowerShellCookbook ) { + Remove-Module PowerShellCookbook + + Import-Module PowerShellCookbook -Cmdlet Add-ObjectCollector +} +# +. Get-Command Add-ObjectCollector -ErrorAction SilentlyContinue | ForEach-Object { + Add-ObjectCollector + Get-Item function:/Add-ObjectCollector | Remove-Item +} diff --git a/profile.d/MyConfig.class.ps1 b/profile.d/MyConfig.class.ps1 new file mode 100644 index 0000000..4e7c457 --- /dev/null +++ b/profile.d/MyConfig.class.ps1 @@ -0,0 +1,61 @@ +class MyConfig { #: System.Management.Automation.IValidateSetValuesGenerator { + hidden static [hashtable]$_HardCodedConfigDict = @{ + 'myconfig' = @($(Join-Path $(Join-Path $MyPSScriptRoot 'src') 'config.files.json'), + $(Join-Path $(Join-Path $MyPSScriptRoot 'src') 'config.files.local.json')) + 'mymodules' = @($(Join-Path $(Join-Path $MyPSScriptRoot 'src') 'modules.json'), + $(Join-Path $(Join-Path $MyPSScriptRoot 'src') 'modules.local.json')) + } + + static [hashtable]GetConfigDictionary() { + $local:result = @{} + [MyConfig]::_HardCodedConfigDict.Keys | ForEach-Object { $result[$_] = [MyConfig]::_HardCodedConfigDict[$_] } + foreach( $local:jsonSource in $result.myconfig ) { + if( -not ( Test-Path $jsonSource ) ) { continue } + foreach( $local:prop in $(Get-Content $jsonSource | ConvertFrom-Json).PSObject.Properties ) { + $result[$prop.Name] = $prop.Value + } + } + return $result; + } + static [string[]] GetConfigPaths([string[]]$ConfigNames,[switch]$Force) { + $local:configDirectory = [MyConfig]::GetConfigDictionary() + $local:result = [string[]]@() + $local:flat = $false + while(-not $flat) { + $flat = $true + $ConfigNames += $ConfigNames | ForEach-Object { + $configDirectory[$_] + } | Where-Object { $_ -match '^#[\w-\.]+$' } | ForEach-Object { + $_.Substring(1) + } | Where-Object { $_ -notin $ConfigNames } | ForEach-Object { + $flat = false; $_; + } + } + + $local:flatConfigList = $ConfigNames | ForEach-Object { + $configDirectory[$_] + } | Where-Object { $_ -notmatch '^#[\w-\.]+$' } + + $local:exists = $false; + $local:first = $null + foreach( $local:configPath in $flatConfigList ) { + if( -not $first ) { $first = $configPath } + if( $Force -or (Test-Path $configPath) ) { + $result += Get-Path $configPath + $exists = $true + } + } + if( -not $exists -and -not $Force ) { + $result += $first + } + return $result + } + static [string[]] _GetValidValues([string]$wordToComplete,[bool]$Strict) { + $local:possibleValues = [MyConfig]::GetConfigDictionary().Keys + return $(Get-PossibleArguments -WordToComplete $wordToComplete -FullValueSet $possibleValues -Strict:$Strict ); + } + + [String[]] GetValidValues() { + return [MyConfig]::_GetValidValues('',$true) + } +} diff --git a/profile.d/Style.ps1 b/profile.d/Style.ps1 new file mode 100644 index 0000000..7b7f354 --- /dev/null +++ b/profile.d/Style.ps1 @@ -0,0 +1,2 @@ +Get-Command Set-PSReadLineKeyHandler | ForEach-Object { Set-PSReadLineKeyHandler -Key Tab -Function MenuComplete } +Get-Command Set-Theme -ErrorAction SilentlyContinue | ForEach-Object { Set-Theme Paradox } diff --git a/profile.d/SystemName.class.ps1 b/profile.d/SystemName.class.ps1 new file mode 100644 index 0000000..022340f --- /dev/null +++ b/profile.d/SystemName.class.ps1 @@ -0,0 +1,37 @@ +class SystemName { #: System.Management.Automation.IValidateSetValuesGenerator { + static [string[]] _GetValidValues([string]$wordToComplete,[bool]$CurrentOnly,[bool]$Strict) { + $MyPSScriptRoot = "$global:MyPSScriptRoot"; + $local:possibleValues = [ordered]@{} + $possibleValues.out = @() + $possibleValues.Current = @( + $($global:PSVersionTable.OS -split ' '|Select-Object -First 1).Replace('Microsoft','Windows'), + $global:PSVersionTable.Platform, + $global:PSVersionTable.PSEdition + ); + $possibleValues.out = $possibleValues.Current + + if( -not $CurrentOnly ) { + $possibleValues.Platform = @( 'Windows','Linux','Unix' ); + $possibleValues.Edition = @( 'Desktop', 'Core' ); + $possibleValues.Exist = Get-ChildItem (Join-Path $MyPSScriptRoot "sys.*") | ForEach-Object { $_.Name -replace 'sys\.','' }; + $possibleValues.out += $possibleValues.Platform + $possibleValues.Edition + $possibleValues.Exist + } + $possibleValues.out = $possibleValues.out | + Select-Object -Unique | + Sort-Object { + $local:sortName = "zz_$_"; + if( $_ -in $possibleValues.Exist -and $_ -in $possibleValues.Current ) { $sortName[0] = "a" } + elseif( $_ -in $possibleValues.Exist ) { $sortName[0] = "b" } + elseif( $_ -in $possibleValues.Current ) { $sortName[0] = "c" } + if( $_ -in $possibleValues.Platform ) { $sortName[1] = "a" } + if( $_ -in $possibleValues.Edition ) { $sortName[1] = "b" } + $sortName; + } + return $(Get-PossibleArguments -WordToComplete $wordToComplete -FullValueSet $possibleValues.out -Strict:$Strict ); + } + + [String[]] GetValidValues() { + return [SystemName]::_GetValidValues('',$false,$true) + } +} + diff --git a/profile.d/Test-MyModules.ps1 b/profile.d/Test-MyModules.ps1 new file mode 100644 index 0000000..7ac05fc --- /dev/null +++ b/profile.d/Test-MyModules.ps1 @@ -0,0 +1,24 @@ +param([switch]$Force) + +$local:currentSys = [SystemName]::_GetValidValues('',$true,$true); + +if( -not $global:MyModulesWarning -or $Force ) { + $global:MyModulesWarning = @() +} +[MyConfig]::GetConfigPaths('mymodules',$false) | + ForEach-Object { + $local:modules = $( Get-Content $_ | ConvertFrom-Json ); + $modules.Always; + $currentSys | ForEach-Object { $modules."$_" } | Where-Object { $_} + } | Where-Object { + $local:m = $_ + if( $( try { + -not (Get-Module -ListAvailable $m -ErrorAction stop) + } catch { $true } + )) { + $m -notin $global:MyModulesWarning + } + } | ForEach-Object { + $global:MyModulesWarning += $_ + Write-Warning "Missing module: $_" + } \ No newline at end of file diff --git a/profile.d/UnixCompleters.ps1 b/profile.d/UnixCompleters.ps1 new file mode 100644 index 0000000..aeb3a6d --- /dev/null +++ b/profile.d/UnixCompleters.ps1 @@ -0,0 +1,4 @@ +Get-Command Import-UnixCompleters -ErrorAction SilentlyContinue | ForEach-Object { + Import-UnixCompleters + Set-UnixCompleter -ShellType Zsh +} diff --git a/profile.d/env.local.ps1.template b/profile.d/env.local.ps1.template new file mode 100644 index 0000000..80023cb --- /dev/null +++ b/profile.d/env.local.ps1.template @@ -0,0 +1,3 @@ +# $env:DOMAIN_NAME='example.com' +# +# $env:EDITOR='/usr/bin/nvim' diff --git a/profile.d/env.ps1 b/profile.d/env.ps1 new file mode 100644 index 0000000..cdf84f8 --- /dev/null +++ b/profile.d/env.ps1 @@ -0,0 +1 @@ +$env:SZ_SKIP_DEFAULT_SHELL = 1 diff --git a/profile.d/load-z.ps1 b/profile.d/load-z.ps1 new file mode 100644 index 0000000..45cd02b --- /dev/null +++ b/profile.d/load-z.ps1 @@ -0,0 +1 @@ +Get-Module -ListAvailable z | Import-Module \ No newline at end of file diff --git a/src/config.files.json b/src/config.files.json new file mode 100644 index 0000000..a11b946 --- /dev/null +++ b/src/config.files.json @@ -0,0 +1,42 @@ +{ + "neovim": [ + "~/.config/nvim/init.vim", + "~/.config/nvim/vim-plug/plugins.vim", + "#vim", + "#vi" + ], + "sz-shrc": "~/.sz.shrc.sh", + "sz-rc-all": [ + "#sz-aliases-sh", + "#sz-local-rc", + "#sz-shrc", + "#sz-zshrc", + "#zshrc" + ], + "vi": "~/.virc", + "sz-local-rc": "~/.sz.local.sh", + "zshrc": "~/.zshrc", + "ansible": [ + "/etc/ansible/ansible.cfg", + "/opt/ansible/ansible.cfg", + "/opt/ansible/hosts" + ], + "sz-aliases-sh": "~/.sz.aliases.sh", + "vim": [ + "~/.vimrc", + "~/.vim/vimrc" + ], + "sz-zshrc": [ + "~/.sz.zshrc.sh", + "#zshrc" + ], + "tmux": [ + "~/.tmux.conf", + "~/.byobu/.tmux.conf" + ], + "ssh-pub": "~/.ssh/id_*.pub", + "ssh-id": ["~/.ssh/id_ed25519","~/.ssh/id_rsa"], + "ssh-auth": "~/.ssh/authorized_keys", + "ssh-conf": "/etc/ssh/sshd_config", + "ssh" : [ "#ssh-auth", "#ssh-conf", "#ssh-pub", "#ssh-id" ] +} diff --git a/src/modules.json b/src/modules.json new file mode 100644 index 0000000..4c33ec3 --- /dev/null +++ b/src/modules.json @@ -0,0 +1,14 @@ +{ + "Always": [ + "PowerShellCookbook", + "oh-my-posh", + "posh-git", + "z" + ], + "Desktop": [ + ], + "Unix": [ + "Microsoft.PowerShell.UnixCompleters" + ] + +} diff --git a/src/smartsudo.inc.ps1 b/src/smartsudo.inc.ps1 new file mode 100644 index 0000000..0dee229 --- /dev/null +++ b/src/smartsudo.inc.ps1 @@ -0,0 +1,18 @@ +function smartsudo() { +[CmdletBinding(SupportsShouldProcess)]param( + [switch]$sudo, + [switch]$Force, + [Parameter(Position = 0, ValueFromRemainingArguments = $true)] + [string[]]$expr +) + + if( $sudo -and -not $(Test-IsAdmin) ) { + Write-Verbose "Perofrming the following command line via SUDO:`n$($expr -join ' ')" + $local:base64command = ConvertTo-Base64 "$expr" + /usr/bin/env sudo pwsh -EncodedCommand $base64command + return + } + + Write-Verbose "Perofrming the following expression in-line:`n$($expr -join ' ')" + Invoke-Expression "$expr" +} diff --git a/sys.Linux/Get-PlexInfo.ps1 b/sys.Linux/Get-PlexInfo.ps1 new file mode 100644 index 0000000..f679500 --- /dev/null +++ b/sys.Linux/Get-PlexInfo.ps1 @@ -0,0 +1,31 @@ +param([switch]$FetchFromServer,[string]$PlexHost='localhost',[switch]$PassThruOnly) + +$local:content = $(try{(Get-Content /run/plex.stream.counter/sessions -Raw -ErrorAction Stop)}catch{}) + +if( $FetchFromServer ) { + $local:creds = New-Object System.Management.Automation.PsCredential($env:PLEX_USERNAME,$(ConvertTo-SecureString -AsPlainText $env:PLEX_PASSWORD -Force)) + $local:webResp = Invoke-WebRequest -Headers @{ "Content-Length" = "0"; "X-Plex-Client-Identifier" = "my-app" } -Credential $creds -Method Post -Uri "https://my.plexapp.com/users/sign_in.xml" + $local:plexHeaders = @{ "X-Plex-Token" = ([xml]$webResp.Content).user.authenticationToken } + $webResp = Invoke-WebRequest -Headers $plexHeaders "http://${PlexHost}:32400" + $local:plexVersion = ([xml]$webResp.Content).MediaContainer.version + Write-Host -ForegroundColor Cyan "Plex Version: $plexVersion" + $webResp = Invoke-WebRequest -Headers $plexHeaders "http://${PlexHost}:32400/status/sessions" + $content = $webResp.Content +} + +$local:PlexInfo = $(try{([xml]$content).MediaContainer}catch{}) + +$local:result = $PlexInfo.ChildNodes | ForEach-Object { [PSCustomObject]@{ + Object = $_ + Type = $_.type + Library = $_.librarySectionTitle + Title = $(@($_.grandparentTitle,$_.parentIndex,$_.parentTitle,$_.index,$_.title) | Where-Object {$_}) -join ' | ' + User = $_.User.title + Offset = [TimeSpan]::FromMilliseconds($_.viewOffset).ToString() -split '\.' | select-object -first 1 + Duration = [TimeSpan]::FromMilliseconds($_.duration).ToString() -split '\.' | select-object -first 1 + Player = "$($_.Player.Platform)|$($_.Player.State)" +# UpdateTime = [TimeSpan]::FromMilliseconds($_.).ToString() +} } + +if( $PassThruOnly ) { return $result } +$result | Format-Table diff --git a/sys.Linux/Invoke-ViaAnsible.ps1 b/sys.Linux/Invoke-ViaAnsible.ps1 new file mode 100644 index 0000000..242ecdc --- /dev/null +++ b/sys.Linux/Invoke-ViaAnsible.ps1 @@ -0,0 +1,49 @@ +[CmdletBinding()]param( + [string[]]$Command, + [string[]]$Remotes = 'all', + [string[]]$MoreArgs, + [switch]$NotPowerShell, + [switch]$OneLine +) + +$script:ansible_cli=@('ansible') +if( (Test-Path './ansible.cfg') -or (Test-Path '/opt/ansible/hosts') -and (Test-Path '/opt/ansible/ssh_key_for_ansible') ) { + $ansible_cli += '-i', '/opt/ansible/hosts', '--private-key=/opt/ansible/ssh_key_for_ansible' +} +if( $Command ) { + $ansible_cli += '-a' + $ansible_cli += 'ANSIBLE_PYTHON_INTERPRETER=auto_silent ' + $ansible_cli += '-a' + if( $NotPowerShell ) { + $ansible_cli += $(($Command -join '; ').Replace("'","\`$(printf '\x27')").Replace('"',"\`$(printf '\x22')")) + } else { + $ansible_cli += "pwsh -encodedcommand $(ConvertTo-Base64 $($Command -join '; '))" + } +} +if( $OneLine ) { + $ansible_cli += '--one-line' +} +$ansible_cli += $Remotes +$ansible_cli += $MoreArgs + +$local:expr = $('& "'+$($ansible_cli -join '" "')+'"') +Write-Verbose $expr +$local:SaveConsoleColor = [Console]::ForegroundColor +$env:ANSIBLE_DEPRECATION_WARNINGS='false' +Invoke-Expression $expr | ForEach-Object { + if( -not $OneLine ) { return $_ }; + $local:res = $_.Split('|'); + $res = [PSCustomObject]([ordered]@{ + Machine = $res[0].Trim(); + Status = $res[1].Trim(); + RC = "$($res[2])".Trim(); + Output = "$($res[3])".Trim(); + }) + if( $res.Status -match '^\w+!:' ) { + [Console]::ForegroundColor = [ConsoleColor]::Red + } else { + [Console]::ForegroundColor = [ConsoleColor]::Yellow + } + $res +} +[Console]::ForegroundColor = $SaveConsoleColor diff --git a/sys.Linux/Pull-ViaAnsible.ps1 b/sys.Linux/Pull-ViaAnsible.ps1 new file mode 100644 index 0000000..8b53770 --- /dev/null +++ b/sys.Linux/Pull-ViaAnsible.ps1 @@ -0,0 +1,3 @@ +[CmdletBinding()]param([string[]]$Remotes = 'All') + +Invoke-ViaAnsible -Command "git pull" -Remotes:$($Remotes.ToLower()) diff --git a/sys.Linux/Update-ArchOSz.ps1 b/sys.Linux/Update-ArchOSz.ps1 new file mode 100644 index 0000000..2c8e0b2 --- /dev/null +++ b/sys.Linux/Update-ArchOSz.ps1 @@ -0,0 +1,13 @@ +param( + [ValidateSet('List','Update','Auto','All')] + [string]$Mode = 'List' +) + +$script:yayCli = "cat /run/check.yay.updates/list" +switch( $Mode ){ + 'Update' { $yayCli = "yay -Syu --needed --ignore docker,linux,linux-api-headers,linux-firmware,linux-headers,zfs-linux" } + 'Auto' { $yayCli = "yay -Syu --needed --noconfirm --ignore docker || yay -Syu --needed --ignore docker,linux,linux-api-headers,linux-firmware,linux-headers,zfs-linux --noconfirm" } + 'All' { $yayCli = "yay -Syu --needed" } +} + +& sh "-c" "$yayCli" -replace '#args',"$args" diff --git a/sys.Linux/Update-OSz.ps1 b/sys.Linux/Update-OSz.ps1 new file mode 100644 index 0000000..a82dfcc --- /dev/null +++ b/sys.Linux/Update-OSz.ps1 @@ -0,0 +1,10 @@ +param( + [ValidateSet('List','Update','Auto','All')] + [string]$Mode = 'List' +) + +$local:detectedDisistro = cat /etc/os-release | Select-String -Pattern "^ID=" | ForEach-Object { $_ -split '=' | Select-Object -Skip 1 } +switch ($detectedDisistro) { + 'arch' { Update-ArchOSz -Mode:$Mode $args } + 'ubuntu' { Update-UbuntuOSz -Mode:$Mode $args } +} diff --git a/sys.Linux/Update-UbuntuOSz.ps1 b/sys.Linux/Update-UbuntuOSz.ps1 new file mode 100644 index 0000000..71bc9bf --- /dev/null +++ b/sys.Linux/Update-UbuntuOSz.ps1 @@ -0,0 +1,14 @@ +param( + [ValidateSet('List','Update','Auto','All')] + [string]$Mode = 'List' +) + +$script:aptCli = "echo 'not defined'" +switch( $Mode ){ + 'List' { } + 'Auto' { $aptCli = "sudo apt-get update && sudo apt-get upgrade --auto-remove --assume-yes" } + default { $aptCli = "sudo apt-get update && sudo apt-get upgrade --auto-remove " } +} + +& sh "-c" "$aptCli" -replace '#args',"$args" + diff --git a/sys.Linux/Update-ViaAnsible.ps1 b/sys.Linux/Update-ViaAnsible.ps1 new file mode 100644 index 0000000..7433136 --- /dev/null +++ b/sys.Linux/Update-ViaAnsible.ps1 @@ -0,0 +1,3 @@ +[CmdletBinding()]param([string[]]$Remotes = 'All') + +Invoke-ViaAnsible -Command "Update-OSz -Mode Auto" -Remotes:$($Remotes.ToLower()) diff --git a/sys.Linux/ls.ps1 b/sys.Linux/ls.ps1 new file mode 100644 index 0000000..89ef76e --- /dev/null +++ b/sys.Linux/ls.ps1 @@ -0,0 +1,5 @@ +$local:params = $args -join ' ' +if( -not $params ) { $params = '-lah' } + +/usr/bin/env ls --color=auto $params + diff --git a/sys.Linux/sranger.ps1 b/sys.Linux/sranger.ps1 new file mode 100644 index 0000000..d8146d3 --- /dev/null +++ b/sys.Linux/sranger.ps1 @@ -0,0 +1 @@ +Invoke-ExpressionEx -sudo "`$env:TERM='tmux-256color'; `$env:EDITOR='$env:EDITOR'; ranger $args" diff --git a/sys.Linux/sz-rsync.ps1 b/sys.Linux/sz-rsync.ps1 new file mode 100644 index 0000000..6b5cd89 --- /dev/null +++ b/sys.Linux/sz-rsync.ps1 @@ -0,0 +1,6 @@ +#setopt dotglob +$szSrc="'$($args -join "','")'" +$szSrcCount=$(Invoke-ExpressionEx -sudo "& find $szSrc -type f | wc -l ) +Invoke-ExpressionEx -sudo "& rsync --archive --acls --xattrs --human-readable -v $szSrc /szmedia/media/ | pv -lepts $szSrcCount" +#unsetopt dotglob + diff --git a/sys.Linux/txm.ps1 b/sys.Linux/txm.ps1 new file mode 100644 index 0000000..e0f0b55 --- /dev/null +++ b/sys.Linux/txm.ps1 @@ -0,0 +1 @@ +tmux set-option mouse $args diff --git a/sz-df.ps1 b/sz-df.ps1 new file mode 100644 index 0000000..c1adf10 --- /dev/null +++ b/sz-df.ps1 @@ -0,0 +1,35 @@ +param([ValidateSet('KB','GB','TB')]$SizeUnitName = 'GB') +$local:zpool_cmd = $null +$local:excludeType = '' + +$script:SizeUnit = Invoke-Expression "1$SizeUnitName" +$script:SizeRound = 2 +$SizeUnit /= 1KB + +function NewDataRow{param($Size,$Used,$Available,$Percent,$Source,$FSType,$Target) + [PSCustomObject]@{ + "Size$SizeUnitName" = [Math]::Round($Size /$SizeUnit, $SizeRound) + "Used$SizeUnitName" = [Math]::Round($Used /$SizeUnit, $SizeRound) + "Available$SizeUnitName" = [Math]::Round($Available/$SizeUnit, $SizeRound) + 'Used%' = [int]($Percent -replace '%$','') + Source = $Source + FSType = $FSType + Target = $Target + } +} + +$local:df = @() +& df '--output=size,used,avail,pcent,source,fstype,target' | + Select-Object -Skip 1 | ForEach-Object { + $local:df = $_.Split(' ', [StringSplitOptions]::RemoveEmptyEntries) + NewDataRow $df[0] $df[1] $df[2] $df[3] $df[4] $df[5] $df[6] + } | Where-Object { + -not ($_.FSType -eq 'zfs' -and $_.Source -match '/') + } | Sort-Object -Property Target + +#$zpool_cmd = get-command zpool | Where-Object CommandType -eq 'Application' | Select-Object -ExpandProperty Source +#if( $zpool_cmd ) { +# $excludeType = '--exclude-type=zfs' +#} + + diff --git a/sz-du.ps1 b/sz-du.ps1 new file mode 100644 index 0000000..134e3bf --- /dev/null +++ b/sz-du.ps1 @@ -0,0 +1 @@ +sudo /bin/du --human-readable --max-depth=1 --one-file-system $args | sort --human-numeric-sort --reverse