Timetombs

泛义的工具是文明的基础,而确指的工具却是愚人的器物

66h / 113a
,更新于 2023-03-18T18:00:58Z+08:00 by   915fbfa

[PowerShell] Script

版权声明 - CC BY-NC-SA 4.0

1 Script File List

ps1文件列表
#####################################################
# current user powershell profile entry script file.
#####################################################

# params
Param(
    [switch]$Init = $False,
    [string]$GitUserName = 'lnh',
    [string]$GitUserEmail = 'lnhdyx@outlook.com'
)

@(
    '/function.ps1',
    '/log.ps1',
    '/env.ps1',
    '/file.ps1',
    '/git.ps1',
    '/vscode.ps1',
    '/gui.ps1',
    '/hosts.ps1',
    '/profile.ps1',
    '/prompt.ps1',
    '/sln.ps1',
    '/ui.ps1',
    '/vm.ps1',
    '/http.ps1',
    '/yaml.ps1',
    '/ip.ps1',
    '/k8s.ps1',
    '/docker.ps1',
    '/hugo.ps1',
    '/java.ps1',
    '/wlan.ps1',
    '/directory.ps1',
    '/idea.ps1',
    '/auto-complete.ps1',
    '/alias.ps1'
) | Foreach-Object { . "$PSScriptRoot$_" }

if ($Init) {

    Profile-AddScriptFile -ProfilePath $PROFILE -ScriptFilePath $PSCOMMANDPATH

    Git-SetGlobalAlias

    Git-SetGlobalConfig

    Git-SetGlobalUser -UserName $GitUserName -UserEmail $GitUserEmail

    Git-GetConfig

    Update-Help
}

Git-ImportPoshGit

Kubernetes-ImportPSKubectlCompletion

UI-SetDisplayOptions

Write-Host "Get-ExecutionPolicy $(Get-ExecutionPolicy)" -ForegroundColor Green
################################
# powershell alias functions
################################


Set-Alias -Name d -Value Directory-To
Set-Alias -Name dq -Value Directory-Search-Path-List-From-Quick-Access
Set-Alias -Name dql -Value Directory-List-Quick-Access
Set-Alias -Name c -Value VsCode-Open
Set-Alias -Name i -Value Idea-Open

Set-Alias -Name dr -Value Docker-Run
Set-Alias -Name dre -Value Docker-Run-entrypoint
Set-Alias -Name drs -Value Docker-Run-entrypoint-sh
Set-Alias -Name drb -Value Docker-Run-entrypoint-bash
Set-Alias -Name dc -Value docker-compose
Set-Alias -Name dm -Value docker-machine
Set-Alias -Name k -Value kubectl
Set-Alias -Name mk -Value minikube

Set-Alias -Name e -Value Gui-OpenExplorer

Set-Alias -Name g -Value git

Set-Alias -Name gti -Value git

Set-Alias -Name hs -Value http-server

Set-Alias -Name hus -Value hugo-server

Set-Alias -Name env -Value Env-GetAllVariable

Set-Alias -Name path -Value Env-GetPathVariavle

Set-Alias -Name yj -Value Yaml-ToJson

Set-Alias -Name jy -Value Yaml-FromJson

Set-Alias -Name grep -Value Select-String

Set-Alias -Name k8sgtp -Value Kubernetes-GetTerminatedPod

Set-Alias -Name ja -Value Java-Arthas
# https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/register-argumentcompleter?view=powershell-7.1

Register-ArgumentCompleter -CommandName Directory-To -ParameterName Path -ScriptBlock $__QUICK_ACCESS_DIRECTORY_SCRIPT_BLOCK
Register-ArgumentCompleter -CommandName VsCode-Open -ParameterName Path -ScriptBlock $__QUICK_ACCESS_DIRECTORY_SCRIPT_BLOCK
Register-ArgumentCompleter -CommandName Idea-Open -ParameterName Path -ScriptBlock $__QUICK_ACCESS_DIRECTORY_SCRIPT_BLOCK
Register-ArgumentCompleter -CommandName Gui-OpenExplorer -ParameterName Path -ScriptBlock $__QUICK_ACCESS_DIRECTORY_SCRIPT_BLOCK

Register-ArgumentCompleter -Native -CommandName winget -ScriptBlock {
    param($wordToComplete, $commandAst, $cursorPosition)
    [Console]::InputEncoding = [Console]::OutputEncoding = $OutputEncoding = [System.Text.Utf8Encoding]::new()
    $Local:word = $wordToComplete.Replace('"', '""')
    $Local:ast = $commandAst.ToString().Replace('"', '""')
    winget complete --word="$Local:word" --commandline "$Local:ast" --position $cursorPosition | ForEach-Object {
        [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
    }
}

Register-ArgumentCompleter -Native -CommandName dotnet -ScriptBlock {
    param($wordToComplete, $commandAst, $cursorPosition)
    dotnet complete --position $cursorPosition $commandAst.ToString() | ForEach-Object {
        [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
    }
}

# https://docs.microsoft.com/en-us/powershell/module/psreadline/get-psreadlinekeyhandler?view=powershell-7.1
# Get-PSReadLineKeyHandler
$__QUICK_ACCESS_DIRECTORY = [System.Collections.Generic.List[PSObject]]::new();

$__QUICK_ACCESS_DIRECTORY_SCRIPT_BLOCK = {
    param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
    Directory-Search-Path-List-From-Quick-Access -Search $wordToComplete | ForEach-Object {
        [System.Management.Automation.CompletionResult]::new($_.FullPath, $_.FullPath, 'ParameterValue', $_.FullPath)
    }
}

function Directory-Exists-And-Is-Directory {
    param (
        [Parameter(Mandatory = $TRUE)]
        [string] $Path = $(throw "Path param is null!")
    )

    if (![System.IO.Directory]::Exists($Path)) {
        throw "path $Path is not exist."
    }

    if ([System.IO.File]::Exists($Path)) {
        throw "path $Path is a file."
    }

    return $TRUE;
}

function script:Directory-Get-Abbr {
    param (
        [Parameter(Mandatory = $TRUE)]
        [string] $Name = $(throw "Name param is null!")
    )
    $Abbr = "";
    $Words = $Name.Split(" _.-".ToCharArray(), [System.StringSplitOptions]::RemoveEmptyEntries);
    $Words | ForEach-Object {
        $Abbr += $_[0];
    }
    return $Abbr;
}

function script:Directory-ConvertToDirObject {
    param ($Raw)
    $FullPath = $Raw.FullName;
    $Name = (Split-Path -Path $FullPath -Leaf);
    $NameAbbr = (Directory-Get-Abbr -Name $Name);

    $Parent = (Split-Path -Path $FullPath -Parent);
    $ParentName = (Split-Path -Path $Parent -Leaf);
    $ParentNameAbbr = (Directory-Get-Abbr -Name $ParentName);
    $Dir = New-Object PSObject -Property @{
        #Raw      = $Raw;
        Abbr     = "$ParentNameAbbr$NameAbbr";
        NameAbbr = $NameAbbr;
        FullPath = $FullPath;
    }
    return $Dir
}

function Directory-Add-To-Quick-Access {
    param (
        [string] $Path
    )

    if (Directory-Exists-And-Is-Directory -Path $Path) {
        Get-ChildItem -Path $Path | ForEach-Object {
            if (Test-Path -Path $_.FullName -PathType Container) {
                $__QUICK_ACCESS_DIRECTORY.Add((Directory-ConvertToDirObject -Raw $_))
            }
        }
    }
}

function Directory-List-Quick-Access {
    $__QUICK_ACCESS_DIRECTORY | Format-Table -AutoSize
}

function Directory-Search-Path-List-From-Quick-Access {
    param (
        [Parameter(Mandatory = $TRUE)]
        [string] $Search = $(throw "Search param is null!")
    )

    $ResultWithScopeIndex = [PSObject[][]]::new(10);
    $__QUICK_ACCESS_DIRECTORY | ForEach-Object {
        $Score = Directory-Search-Score -Dir $_ -Search $Search
        if ($Score -gt -1) {
            $ResultWithScopeIndex[$Score] += $_
        }
    }
    [array]::Reverse($ResultWithScopeIndex);

    $Result = [System.Collections.Generic.List[PSObject]]::new();
    $ResultWithScopeIndex | ForEach-Object {
        if ($_ -ne $NULL) {
            $Result.AddRange($_)
        }
    }

    return $Result;
}

function script:Directory-Search-Score {
    param ($Dir, [string] $Search )
    if ($Dir.FullPath.Contains($Search, [StringComparison]::OrdinalIgnoreCase)) {
        return 9;
    }
    if ($Dir.Abbr.Contains($Search, [StringComparison]::OrdinalIgnoreCase)) {
        return 8;
    }
    if ($Dir.NameAbbr.Contains($Search, [StringComparison]::OrdinalIgnoreCase)) {
        return 7;
    }
    if (Filter-Directory-Item -Dir $Dir -Search $Search) {
        return 1;
    }

    return -1;
}


function script:Filter-Directory-Item {
    param ($Dir, [string] $Search )
    $StartIndex = 0;
    for ($i = 0; $i -lt $Search.Length; $i++) {
        $char = $Search[$i];
        $charIndex = $Dir.FullPath.IndexOf($char, $StartIndex);
        if ($charIndex -eq -1) {
            return $FALSE;
        }
        else {
            $StartIndex = $charIndex;
        }
    }
    return $TRUE;
}

function Directory-To {
    param (
        [Parameter(Mandatory = $TRUE)]
        [string] $Path = $(throw "Path param is null!")
    )
    if (Directory-Exists-And-Is-Directory -Path $Path) {
        Log-Debug "cd $Path".ToLower()
        Set-Location $Path
    }
}

Directory-Add-To-Quick-Access -Path d:/_code/
Directory-Add-To-Quick-Access -Path d:/_github/
Directory-Add-To-Quick-Access -Path d:/
Directory-Add-To-Quick-Access -Path d:/_app/
Directory-Add-To-Quick-Access -Path d:/_cache/
function Docker-Run() {
    Log-Debug "docker run --rm --tty --interactive" $Args
    docker run --rm --tty --interactive $Args
}
function Docker-Run-entrypoint() {
    Log-Debug "docker run --rm --tty --interactive --entrypoint" $Args
    docker run --rm --tty --interactive --entrypoint $Args
}

function Docker-Run-entrypoint-sh() {
    Log-Debug "docker run --rm --tty --interactive --entrypoint sh" $Args
    docker run --rm --tty --interactive --entrypoint sh $Args
}

function Docker-Run-entrypoint-bash() {
    Log-Debug "docker run --rm --tty --interactive --entrypoint bash" $Args
    docker run --rm --tty --interactive --entrypoint bash $Args
}
################################
# powershell env functions
################################

[string]$APP_DIR    = 'd:\_app\';
[string]$CACHE_DIR  = 'd:\_cache\';
[string]$CONFIG_DIR = 'd:\_config\';
[string]$DATA_DIR   = 'd:\_data\';

function script:Env-TrySetVariable (
    [string]$Variable = $(throw "Variable is null!"),
    [string]$Value = $(throw "Value is null!")
) {
    $Target = [System.EnvironmentVariableTarget]::Machine

    # 输出旧值
    [string]$OldValue = [System.Environment]::GetEnvironmentVariable($Variable, $Target);
    Log-Info "[$Target][$Variable] OLD_VALUE : " $OldValue

    if ($OldValue -eq $Value) {
        Log-Warn "[$Target][$Variable] NEW_VALUE : " $Value
        return
    }

    # 设置环境变量
    [System.Environment]::SetEnvironmentVariable($Variable, $Value, $Target)

    # 输出新值
    [string]$NewValue = [System.Environment]::GetEnvironmentVariable($Variable, $Target);
    Log-Debug "[$Target][$Variable] NEW_VALUE : " $NewValue
    Write-Host
}

function script:Env-TryAppendPathVariable (
    [string]$Value = $(throw "Value is null!")
) {
    $Target = [System.EnvironmentVariableTarget]::Machine
    $Variable = 'Path'
    # 获取旧值
    [string]$OldValue = [System.Environment]::GetEnvironmentVariable($Variable, $Target);

    # 检测是否已经存在
    if ($OldValue.Split(';').Contains($Value)) {
        Log-Warn "[$Target][$Variable] EXISTS_VALUE : $Value"
        return
    }

    Log-Debug "[$Target][$Variable] APPEND_VALUE : $Value"

    # 追加新值
    [string]$NewValue = $OldValue;
    if ($OldValue.EndsWith(';')) {
        $NewValue = $OldValue + $Value + ';'
    }
    else {
        $NewValue = $OldValue + ';' + $Value + ';'
    }

    Env-TrySetVariable -Variable $Variable -Value $NewValue
}


function Env-TrySetAll() {
    Get-Command -Name 'Env-Set*EnvironmentVariable' -CommandType Function | ForEach-Object {
        Log-Info "RUN : $($_.Name)"
        Invoke-Expression -Command $_.Name
        Write-Host
        Write-Host
    }
}

function Env-GetAllVariable() {
    Get-ChildItem ENV:
}

function Env-GetPathVariavle() {
    $ENV:PATH.Split(';')
}

# https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
function Env-SetXDGEnvironmentVariable() {
    Env-TrySetVariable -Variable 'XDG_CONFIG_HOME' -Value $CONFIG_DIR
    Env-TrySetVariable -Variable 'XDG_CACHE_HOME' -Value $CACHE_DIR
    Env-TrySetVariable -Variable 'XDG_DATA_HOME' -Value $DATA_DIR
}

# https://github.com/MicrosoftArchive/redis/releases
function Env-SetRedisEnvironmentVariable() {
    $APP_REDIS_DIR = $APP_DIR + '_redis\';

    Env-TryAppendPathVariable -Value $APP_REDIS_DIR
}

# https://www.mongodb.org/dl/win32/x86_64-2008plus-ssl
function Env-SetMongoDBEnvironmentVariable() {
    $APP_MONGO_DIR = $APP_DIR + '_mongo\';

    Env-TryAppendPathVariable -Value $APP_MONGO_DIR
}

# https://www.putty.org/
function Env-SetPuttyEnvironmentVariable() {
    $APP_PUTTY_DIR = $APP_DIR + '_putty\';

    Env-TryAppendPathVariable -Value $APP_PUTTY_DIR
}

# https://github.com/shadowsocks/shadowsocks-windows
# function Env-SetShadowsocksEnvironmentVariable() {
#     $APP_SHADOWSOCKS_DIR = $APP_DIR + '_shadowsocks\';

#     Env-TryAppendPathVariable -Value $APP_SHADOWSOCKS_DIR
# }

# https://adoptopenjdk.net/upstream.html
# https://developers.redhat.com/products/openjdk/download
function Env-SetJavaEnvironmentVariable() {
    $APP_JAVA_DIR = $APP_DIR + '_java\';
    $APP_JAVA_BIN_DIR = $APP_JAVA_DIR + 'bin\';

    Env-TrySetVariable -Variable 'JAVA_TOOL_OPTIONS' -Value '-Dfile.encoding=UTF-8'

    Env-TrySetVariable -Variable 'JAVA_HOME' -Value $APP_JAVA_DIR

    Env-TryAppendPathVariable -Value $APP_JAVA_BIN_DIR
}

# https://golang.org/doc/install
function Env-SetGoEnvironmentVariable() {
    $APP_GO_DIR = $APP_DIR + '_go\';
    $APP_GO_BIN_DIR = $APP_GO_DIR + 'bin\';

    $CACHE_GO_DIR = $CACHE_DIR + '_go\';

    Env-TrySetVariable -Variable 'GOROOT' -Value $APP_GO_DIR
    Env-TrySetVariable -Variable 'GOCACHE' -Value $CACHE_GO_DIR
    Env-TryAppendPathVariable -Value $APP_GO_BIN_DIR
}

# https://rubyinstaller.org/downloads/
function Env-SetRubyEnvironmentVariable() {
    $APP_RUBY_DIR = $APP_DIR + '_ruby\';
    $APP_RUBY_BIN_DIR = $APP_RUBY_DIR + 'bin\';

    Env-TrySetVariable -Variable 'RUBY_HOME' -Value $APP_RUBY_DIR
    Env-TryAppendPathVariable -Value $APP_RUBY_BIN_DIR
}

# https://nodejs.org/en/download/
function Env-SetNodeEnvironmentVariable() {
    $APP_NODE_DIR = $APP_DIR + '_node\';
    $APP_NODE_MODULES_DIR = $APP_NODE_DIR + 'node_modules\';

    $CACHE_NODE_DIR = $CACHE_DIR + '_node\';

    Env-TrySetVariable -Variable 'NODE_PATH' -Value $APP_NODE_MODULES_DIR
    Env-TryAppendPathVariable -Value $APP_NODE_DIR

    npm config set cache $CACHE_NODE_DIR --global
    npm config set registry "https://registry.npm.taobao.org" --global
    npm install -g cnpm --registry=https://registry.npm.taobao.org
}


# https://kotlinlang.org/docs/tutorials/command-line.html
function Env-SetKotlinEnvironmentVariable() {
    $APP_KOTLIN_DIR = $APP_DIR + '_kotlin\'
    $APP_KOTLIN_BIN_DIR = $APP_KOTLIN_DIR + 'bin\'

    Env-TryAppendPathVariable -Value $APP_KOTLIN_BIN_DIR
}


# https://dotnet.github.io/
# https://docs.microsoft.com/en-us/dotnet/core/tools/telemetry
function Env-SetNetEnvironmentVariable() {
    Env-TrySetVariable -Variable 'DOTNET_CLI_TELEMETRY_OPTOUT' -Value "true"
}

# https://www.python.org/downloads/windows/
# Windows x86-64 embeddable zip file
function Env-SetPythonEnvironmentVariable() {
    $APP_PYTHON_DIR = $APP_DIR + '_python\';
    $APP_PYTHON_SCRIPTS_DIR = $APP_PYTHON_DIR + 'scripts\';

    Env-TryAppendPathVariable -Value $APP_PYTHON_DIR
    Env-TryAppendPathVariable -Value $APP_PYTHON_SCRIPTS_DIR
}

# https://github.com/icsharpcode/ILSpy/releases
function Env-SetILSpyEnvironmentVariable() {
    $APP_ILSPY_DIR = $APP_DIR + '_ilspy\';

    Env-TryAppendPathVariable -Value $APP_ILSPY_DIR
}

# https://www.nuget.org/downloads
# https://docs.microsoft.com/en-us/nuget/tools/cli-ref-environment-variables
function Env-SetNugetEnvironmentVariable() {
    $APP_NUGET_DIR = $APP_DIR + '_nuget\';

    $CACHE_NUGET_DIR = $CACHE_DIR + '_nuget\';

    Env-TrySetVariable -Variable 'NUGET_PACKAGES' -Value $CACHE_NUGET_DIR
    Env-TryAppendPathVariable -Value $APP_NUGET_DIR
}

# https://developer.android.com/studio/releases/platform-tools.html
function Env-SetADBEnvironmentVariable() {
    $APP_ADB_DIR = $APP_DIR + '_adb\';

    Env-TryAppendPathVariable -Value $APP_ADB_DIR
}

# https://www.cpuid.com/softwares/cpu-z.html
function Env-SetCPUZEnvironmentVariable() {
    $APP_CPUZ_DIR = $APP_DIR + '_cpu-z\';

    Env-TryAppendPathVariable -Value $APP_CPUZ_DIR
}

# https://www.techpowerup.com/gpuz/
function Env-SetGPUZEnvironmentVariable() {
    $APP_GPUZ_DIR = $APP_DIR + '_gpu-z\';

    Env-TryAppendPathVariable -Value $APP_GPUZ_DIR
}

# http://www.superpi.net/Download/
function Env-SetPIEnvironmentVariable() {
    $APP_PI_DIR = $APP_DIR + '_pi\';

    Env-TryAppendPathVariable -Value $APP_PI_DIR
}

# https://maven.apache.org/
function Env-SetMavenEnvironmentVariable() {
    $APP_MAVEN_DIR = $APP_DIR + '_maven\'
    $APP_MAVEN_BIN_DIR = $APP_MAVEN_DIR + 'bin\'
    $CACHE_MAVEN_DIR = $CACHE_DIR + '_maven\'

    # for maven 1
    Env-TrySetVariable -Variable 'MAVEN_HOME' -Value $APP_MAVEN_DIR

    # for maven 2 or 3
    Env-TrySetVariable -Variable 'M2_HOME' -Value $APP_MAVEN_DIR

    # for maven-wrapper https://github.com/takari/maven-wrapper
    Env-TrySetVariable -Variable 'MAVEN_USER_HOME' -Value $APP_MAVEN_DIR

    # http://maven.apache.org/configure.html
    Env-TrySetVariable -Variable 'MAVEN_OPTS' -Value '-Xms256m -Xmx1024m'

    Env-TryAppendPathVariable -Value $APP_MAVEN_BIN_DIR
}

# https://gradle.org/releases/
# https://docs.gradle.org/current/userguide/installation.html
# https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_environment_variables
function Env-SetGradleEnvironmentVariable() {
    $APP_GRADLE_DIR = $APP_DIR + '_gradle\';
    $APP_GRADLE_BIN_DIR = $APP_GRADLE_DIR + 'bin\';

    $CACHE_GRADLE_DIR = $CACHE_DIR + '_gradle\';

    Env-TrySetVariable -Variable 'GRADLE_HOME' -Value $APP_GRADLE_DIR
    Env-TrySetVariable -Variable 'GRADLE_USER_HOME' -Value $CACHE_GRADLE_DIR
    Env-TryAppendPathVariable -Value $APP_GRADLE_BIN_DIR
}

# https://projects.spring.io/spring-boot/
function Env-SetSpringBootCliEnvironmentVariable() {
    $APP_SPRING_BOOT_CLI_DIR = $APP_DIR + '_spring-boot-cli\';
    $APP_SPRING_BOOT_CLI_BIN_DIR = $APP_SPRING_BOOT_CLI_DIR + 'bin\';

    Env-TryAppendPathVariable -Value $APP_SPRING_BOOT_CLI_BIN_DIR
}

# http://httpd.apache.org/download.cgi
function Env-SetHttpdEnvironmentVariable() {
    $APP_HTTPD_DIR = $APP_DIR + '_httpd\';
    $APP_HTTPD_BIN_DIR = $APP_HTTPD_DIR + 'bin\';

    Env-TryAppendPathVariable -Value $APP_HTTPD_BIN_DIR
}

# https://jmeter.apache.org/download_jmeter.cgi
function Env-SetJmeterEnvironmentVariable() {
    $APP_JMETER_DIR = $APP_DIR + '_jmeter\';
    $APP_JMETER_BIN_DIR = $APP_JMETER_DIR + 'bin\';

    Env-TryAppendPathVariable -Value $APP_JMETER_BIN_DIR
}

# http://nginx.org/en/download.html
function Env-SetNginxEnvironmentVariable() {
    $APP_NGINX_DIR = $APP_DIR + '_nginx\';

    Env-TryAppendPathVariable -Value $APP_NGINX_DIR
}

# https://kubernetes.io/docs/tasks/tools/install-kubectl
function Env-SetKubectlEnvironmentVariable() {
    $APP_KUBECTL_DIR = $APP_DIR + '_kubectl\';

    $CONFIG_KUBECTL_DIR = $CONFIG_DIR + '_kubectl\';
    $CONFIG_KUBECTL_CONFIG_FILE = $CONFIG_KUBECTL_DIR + 'config.yml';

    Env-TrySetVariable -Variable 'KUBECONFIG' -Value $CONFIG_KUBECTL_CONFIG_FILE
    Env-TryAppendPathVariable -Value $APP_KUBECTL_DIR
}

# https://github.com/kubernetes/minikube/releases
# function Env-SetMinikubeEnvironmentVariable() {
#     $APP_MINIKUBE_DIR = $APP_DIR + '_minikube\';
#     $DATA_MINIKUBE_DIR = 'e:\_minikube\';

#     Env-TrySetVariable -Variable 'MINIKUBE_HOME' -Value $DATA_MINIKUBE_DIR
#     Env-TrySetVariable -Variable 'MINIKUBE_WANTUPDATENOTIFICATION' -Value 'false'
#     Env-TrySetVariable -Variable 'MINIKUBE_WANTREPORTERRORPROMPT' -Value 'false'
#     Env-TrySetVariable -Variable 'CHANGE_MINIKUBE_NONE_USER' -Value 'true'
#     Env-TryAppendPathVariable -Value $APP_MINIKUBE_DIR
# }

# https://docs.docker.com/engine/reference/commandline/cli/#environment-variables
# https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-socket-option
function Env-SetDockerEnvironmentVariable() {
    $APP_DOCKER_DIR = $APP_DIR + '_docker\';

    Env-TrySetVariable -Variable 'DOCKER_HOST' -Value 'tcp://127.0.0.1:2375'
    Env-TryAppendPathVariable -Value $APP_DOCKER_DIR
}

# https://docs.docker.com/machine
# https://docs.docker.com/machine/drivers/hyper-v/
# function Env-SetDockerMachineEnvironmentVariable() {
#     $APP_DOCKER_DIR = $APP_DIR + '_docker\';
#     $BOOT2DOCKER_ISO_DIR = 'file://' + $APP_DOCKER_DIR + 'boot2docker.iso';

#     $DATA_DOCKER_DIR = 'e:\_docker\';

#     Env-TrySetVariable -Variable 'MACHINE_STORAGE_PATH' -Value $DATA_DOCKER_DIR
#     Env-TrySetVariable -Variable 'MACHINE_NATIVE_SSH' -Value 1
#     Env-TrySetVariable -Variable 'HYPERV_BOOT2DOCKER_URL' -Value $BOOT2DOCKER_ISO_DIR
#     Env-TrySetVariable -Variable 'HYPERV_VIRTUAL_SWITCH' -Value 'HVS'
#     Env-TrySetVariable -Variable 'HYPERV_CPU_COUNT' -Value 1
#     Env-TrySetVariable -Variable 'HYPERV_MEMORY' -Value 1024
#     Env-TrySetVariable -Variable 'HYPERV_DISK_SIZE' -Value 10240

#     Env-TryAppendPathVariable -Value $APP_DOCKER_DIR
# }

# https://helm.sh/docs
# https://github.com/helm/helm-www
# https://github.com/helm/helm/releases
function Env-SetHelmEnvironmentVariable() {
    $APP_HLEM_DIR = $APP_DIR + '_helm\';

    Env-TryAppendPathVariable -Value $APP_HLEM_DIR
}

# https://github.com/mholt/caddy
# https://caddyserver.com/docs/cli
# function Env-SetCaddyEnvironmentVariable() {
#     $APP_CADDY_DIR = $APP_DIR + '_caddy\';

#     Env-TryAppendPathVariable -Value $APP_CADDY_DIR
# }

# https://coreos.com/os/docs/1911.5.0/overview-of-ct.html
# https://github.com/coreos/container-linux-config-transpiler
# function Env-SetCoreOSEnvironmentVariable() {
#     $APP_COREOS_DIR = $APP_DIR + '_coreos\';

#     Env-TryAppendPathVariable -Value $APP_COREOS_DIR
# }

# https://docs.microsoft.com/en-us/powershell/scripting/overview?view=powershell-6
function Env-SetPowerShellEnvironmentVariable() {
    Env-TrySetVariable -Variable 'POWERSHELL_TELEMETRY_OPTOUT' -Value 'true'
}

# https://github.com/v2ray/v2ray-core
function Env-SetV2RayEnvironmentVariable() {
    $APP_V2RAY_DIR = $APP_DIR + '_v2ray\';

    Env-TryAppendPathVariable -Value $APP_V2RAY_DIR
}

function Env-SetLocaleEnvironmentVariable() {
    Env-TrySetVariable -Variable 'LC_ALL' -Value 'zh_CN.UTF-8'
    Env-TrySetVariable -Variable 'LANG' -Value 'C.UTF-8'
}

# https://www.alex-is.de/PHP/fusion/downloads.php?cat_id=4&download_id=9
function Env-SetASSSDBenchmarkEnvironmentVariable() {
    $APP_AS_SSD_BENCHMARK_DIR = $APP_DIR + '_as-ssd-benchmark\';

    Env-TryAppendPathVariable -Value $APP_AS_SSD_BENCHMARK_DIR
}

# https://crystalmark.info/en/download/
function Env-SetDiskInfoEnvironmentVariable() {
    $APP_DISK_INFO_DIR = $APP_DIR + '_disk-info\';

    Env-TryAppendPathVariable -Value $APP_DISK_INFO_DIR
}

# https://github.com/pbatard/rufus
function Env-SetRufusEnvironmentVariable() {
    $APP_RUFUS_DIR = $APP_DIR + '_rufus\';

    Env-TryAppendPathVariable -Value $APP_RUFUS_DIR
}

# https://github.com/FFmpeg/FFmpeg
function Env-SetFFmpegEnvironmentVariable() {
    $APP_FFMPEG_DIR = $APP_DIR + '_ffmpeg\bin';

    Env-TryAppendPathVariable -Value $APP_FFMPEG_DIR
}

# https://www.rust-lang.org/
function Env-SetRustEnvironmentVariable() {
    $APP_RUSTUP_DIR = $APP_DIR + '_rustup\';
    $APP_CARGO_DIR = $APP_DIR + '_cargo\';
    $APP_CARGO_BIN_DIR = $APP_CARGO_DIR + 'bin\';

    # https://github.com/rust-lang/rustup.rs#environment-variables
    Env-TrySetVariable -Variable 'RUSTUP_HOME' -Value $APP_RUSTUP_DIR
    Env-TrySetVariable -Variable 'RUSTUP_DIST_SERVER' -Value 'http://mirrors.ustc.edu.cn/rust-static'
    Env-TrySetVariable -Variable 'RUSTUP_UPDATE_ROOT' -Value 'http://mirrors.ustc.edu.cn/rust-static/rustup'

    # https://github.com/rust-lang/cargo/blob/master/src/doc/src/reference/environment-variables.md
    Env-TrySetVariable -Variable 'CARGO_HOME' -Value $APP_CARGO_DIR

    Env-TrySetVariable -Variable 'RUST_BACKTRACE' -Value 'full'
    Env-TrySetVariable -Variable 'RUST_TEST_NOCAPTURE' -Value '0'

    Env-TryAppendPathVariable -Value $APP_CARGO_BIN_DIR
}

# https://github.com/gohugoio/hugo
function Env-SetHugoEnvironmentVariable() {
    $APP_HUGO_DIR = $APP_DIR + '_hugo\';

    Env-TryAppendPathVariable -Value $APP_HUGO_DIR
}

# https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format
# https://wiki.wireshark.org/TLS
function Env-SetSslKeyLogFileEnvironmentVariable() {
    $CACHE_SSL_DIR = $CACHE_DIR + '_ssl\';

    $SSLKEYLOGFILE = $CACHE_SSL_DIR + 'ssl.log';

    Env-TrySetVariable -Variable 'SSLKEYLOGFILE' -Value $SSLKEYLOGFILE
}

# https://dev.mysql.com/downloads/mysql/
# https://dev.mysql.com/doc/refman/8.0/en/windows-install-archive.html
# https://dev.mysql.com/doc/refman/8.0/en/environment-variables.html
function Env-SetMySqlEnvironmentVariable() {
    $APP_MYSQL_DIR = $APP_DIR + '_mysql\';
    $CACHE_MYSQL_DIR = $CACHE_DIR + '_mysql\';
    $DATA_MYSQL_DIR = $DATA_DIR + '_mysql\';
    $APP_MYSQL_BIN_DIR = $APP_MYSQL_DIR + 'bin\';
    $MYSQL_HISTFILE = $CACHE_MYSQL_DIR + '.history';

    Env-TrySetVariable -Variable 'MYSQL_HOME' -Value $APP_MYSQL_DIR
    Env-TrySetVariable -Variable 'MYSQL_DATA' -Value $DATA_MYSQL_DIR
    Env-TrySetVariable -Variable 'MYSQL_HISTFILE' -Value $MYSQL_HISTFILE
    Env-TryAppendPathVariable -Value $APP_MYSQL_BIN_DIR
}

# https://github.com/svenstaro/miniserve
function Env-SetMiniServeEnvironmentVariable() {
    $APP_MINISERVE_DIR = $APP_DIR + '_miniserve\';

    Env-TryAppendPathVariable -Value $APP_MINISERVE_DIR
}

# https://github.com/wagoodman/dive
function Env-SetDiveEnvironmentVariable() {
    $APP_DIVE_DIR = $APP_DIR + '_dive\';

    Env-TryAppendPathVariable -Value $APP_DIVE_DIR
}

# https://www.voidtools.com/zh-cn/
function Env-SetEverythingEnvironmentVariable() {
    $APP_EVERYTHING_DIR = $APP_DIR + '_everything\';

    Env-TryAppendPathVariable -Value $APP_EVERYTHING_DIR
}

# iperf2 https://sourceforge.net/projects/iperf2/
# iperf3 https://iperf.fr/
function Env-SetIperfEnvironmentVariable() {
    $APP_IPERF_DIR = $APP_DIR + '_iperf\';

    Env-TryAppendPathVariable -Value $APP_IPERF_DIR
}

# 杂项工具
function Env-SetOtherEnvironmentVariable() {
    $APP_OTHER_DIR = $APP_DIR + '_other\';

    Env-TryAppendPathVariable -Value $APP_OTHER_DIR
}
################################
# powershell file functions
################################

function File-GetBigFiles ([int]$top = 20) {
    $begin = Get-Date
    Log-Debug "begin..." $begin

    Get-ChildItem -Path $(Get-Location) -File -Recurse |
    Sort-Object Length -Descending |
    Select-Object -First $top |
    Format-Table -Property @{Label = "Size"; Expression = { ($_.Length / 1MB).ToString(('0.000')) + 'MB' } }, FullName -Wrap

    $end = Get-Date
    Log-Debug "end..." $end
    Log-Debug "elapsed times" ($end - $begin)
}


function File-GetAll {
    param (
        [string] $Path = $(Get-Location)
    )

    Get-ChildItem -Path $Path -Directory | ForEach-Object {
        File-GetAll -Path $_
    }

    Get-ChildItem -Path $Path -File | ForEach-Object {
        $_.FullName
    }
}

function File-Diff {
    param (
        [string] $PartFile,
        [string] $FullFile
    )

    $PartContent = $(Get-Content $PartFile)
    Get-Content -Path $FullFile | ForEach-Object {
        if ($PartContent.Contains($_) -eq $FALSE) {
            $_
        }
    }
}

function Read-Host-With-Default {
    param (
        [String]$Prompt,
        [String]$DefaultValue
    )
    $Input = Read-Host -Prompt "$Prompt,default $DefaultValue"
    $Input = (-not($input))?"$DefaultValue":"$Input"
    Write-host "$Prompt $Input" -ForegroundColor Green
    return $Input
}
################################
# git functions
################################

# import posh-git module
function Git-ImportPoshGit () {
    Import-Module posh-git
}

# install posh-git module
function Git-InstallPoshGit () {
    Install-Module posh-git
}

# recurse git pull rebase
function Git-Pull-Rebase-Recurse () {
    Get-ChildItem -Attributes Directory -Path (Get-Location) | ForEach-Object {
        $Path = $_.FullName.ToLower()
        Log-Debug "`ncd $Path"
        Set-Location $Path

        Log-Debug 'git remote -v'
        git remote -v

        Log-Debug 'git symbolic-ref HEAD'
        git symbolic-ref HEAD

        Log-Debug "git pull --rebase"
        git pull --rebase

        Set-Location -Path ..
    }
}


function Git-Warn-GC () {
    Log-Debug "git reflog expire --expire=now --all"
    git warn-expire-reflog
    Log-Debug "git gc --prune=now --aggressive"
    git warn-gc-now
    Log-Debug "git count-objects -v -H"
    git size
}

function Git-Warn-GC-Recurse () {
    Get-ChildItem -Attributes Directory -Path (Get-Location) | ForEach-Object {
        $Path = $_.FullName.ToLower()
        Log-Debug "`ncd $Path"
        Set-Location $Path
        Git-Warn-GC
        Set-Location -Path ..
    }
}

function Git-Size-Recurse () {
    Get-ChildItem -Attributes Directory -Path (Get-Location) | ForEach-Object {
        $Path = $_.FullName.ToLower()
        Log-Debug "`ngit -C '$Path' count-objects -v -H"
        git -C "$Path" size
    }
}

function script:Git-GetAllObjects () {
    $gitObjects = git rev-list --objects --all | git cat-file --batch-check='%(objecttype)|%(objectname)|%(objectsize)|%(rest)'
    return $gitObjects
}

function script:Git-ConvertToPSObject ($object) {
    $row = $object.Split('|')

    $gitObject = New-Object PSObject -Property @{
        type = $row[0];
        sha  = $row[1];
        size = [int]($row[2]);
        path = $row[3];
    }

    return $gitObject
}

function script:Git-GetAllBlobObjects () {
    $gitBlobObjects = @()
    Git-GetAllObjects | Foreach-Object {
        if ($_.StartsWith('blob')) {
            $gitBlobObjects += (Git-ConvertToPSObject $_)
        }
    }
    return $gitBlobObjects
}


function Git-GetBigFiles([int]$top = 20) {
    $begin = Get-Date
    Log-Debug "begin..." $begin

    Git-GetAllBlobObjects |
    Sort-Object size -Descending |
    Select-Object -First $top |
    Format-Table -Property sha, @{Label = "size"; Expression = { ($_.size / 1MB).ToString(('0.000')) + 'MB' } }, path -Wrap

    $end = Get-Date
    Log-Debug "end..." $end
    Log-Debug "elapsed times" ($end - $begin)
}

function Git-SetGlobalAlias () {

    # checkout
    git config --global alias.co checkout

    # commit
    git config --global alias.ci commit
    git config --global alias.alc 'commit --amend --no-edit'

    # status
    git config --global alias.st 'status --short --branch'

    # branch
    git config --global alias.br branch

    # pull
    git config --global alias.pr 'pull --rebase'

    # merge
    git config --global alias.mnf 'merge --no-ff'

    # diff
    git config --global alias.d diff
    git config --global alias.dt difftool

    # cherry-pick
    git config --global alias.cp cherry-pick

    # log
    git config --global alias.last 'log -1'
    git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"

    # count-objects
    git config --global alias.size 'count-objects -v -H'

    # reflog
    git config --global alias.rl "reflog --format='%cd %h %gs' --date=format:'%Y-%m-%d %H:%M:%S'"

    # gc
    git config --global alias.warn-expire-reflog "reflog expire --expire=now --all"
    git config --global alias.warn-gc-now "gc --prune=now --aggressive"

    # chmod +/- x
    git config --global alias.chmod644 "update-index --chmod=-x"
    git config --global alias.chmod755 "update-index --chmod=+x"

    # head
    git config --global alias.head 'symbolic-ref HEAD'
}

# set global config
function Git-SetGlobalConfig () {

    git config --global init.defaultBranch main

    # gui
    git config --global gui.encoding 'utf-8'

    # i18n
    git config --global i18n.commitencoding 'utf-8'
    git config --global core.quotepath false

    # editor
    git config --global core.editor "code -w"
    git config --global core.autocrlf false
    git config --global core.safecrlf true
    git config --global core.filemode false

    # color
    git config --global color.ui true

    # branch pager
    git config --global pager.branch false
}

# set git global user
function Git-SetGlobalUser (
    [string] $UserName = $(throw "UserName is null!"),
    [string] $UserEmail = $(throw "UserEmail is null!")
) {

    git config --global user.name $UserName
    git config --global user.email $UserEmail
}

# get git user
function Git-GetCurrentUser () {

    $UserName = git config user.name
    $UserEmail = git config user.email
    return "$UserName@<$UserEmail>"
}

# git get config
function Git-GetConfig ([string]$Name) {
    if ($Name) {
        $Values = git config --get-all $Name
        $LocalValues = git config --get-all --local $Name
        $GlobalValues = git config --get-all --global $Name
        $SystemValues = git config --get-all --system $Name

        Write-Host "name   : $Name" -ForegroundColor Green
        Write-Host "value  : $Values" -ForegroundColor Green
        Write-Host "local  : $LocalValues" -ForegroundColor Green
        Write-Host "global : $GlobalValues" -ForegroundColor Green
        Write-Host "system : $SystemValues" -ForegroundColor Green
    }
    else {
        git config --list | Sort-Object
    }
}

function Git-Proxy(
    [switch]$set = $False,
    [switch]$get = $True,
    [switch]$unset = $False
) {
    if ($set) {
        git config --global http.proxy 'socks5://192.168.2.123:1080'
    }

    if ($unset) {
        git config --global --unset http.proxy
        git config --global --unset https.proxy
    }

    git config --global --get http.proxy
    git config --global --get https.proxy
}
git clone https://github.com/linianhui/benchmark-http.git
git clone https://github.com/linianhui/benchmark-nginx.git
git clone https://github.com/linianhui/blog.git
git clone https://github.com/linianhui/channel9-downloader.git
git clone https://github.com/linianhui/chrome-extensions.git
git clone https://github.com/linianhui/cnblogs-theme.git
git clone https://github.com/linianhui/code.git
git clone https://github.com/linianhui/code-guide.git
git clone https://github.com/linianhui/div.git
git clone https://github.com/linianhui/docker.git
git clone https://github.com/linianhui/example-aspnetcore.git
git clone https://github.com/linianhui/example-cake.git
git clone https://github.com/linianhui/example-java.git
git clone https://github.com/linianhui/example-mongodb.git
git clone https://github.com/linianhui/example-oidc.git
git clone https://github.com/linianhui/example-rabbitmq.git
git clone https://github.com/linianhui/example-spring.git
git clone https://github.com/linianhui/git-web.git
git clone https://github.com/linianhui/I-love-mommy.git
git clone https://github.com/linianhui/jvm.git
git clone https://github.com/linianhui/linianhui.github.io.git
git clone https://github.com/linianhui/networking.git
git clone https://github.com/linianhui/networking-programming.git
git clone https://github.com/linianhui/nuget-server.git

function Gui-OpenExplorer () {
    param (
        [Parameter(Mandatory = $TRUE)]
        [string] $Path = $(throw "Path param is null!")
    )
    if (Directory-Exists-And-Is-Directory -Path $Path) {
        Log-Debug "explorer $Path".ToLower()
        explorer $Path
    }
}

function Hosts-Edit () {
  code "$ENV:SYSTEMROOT\system32\drivers\etc\hosts"
}

# https://github.com/svenstaro/miniserve
function Http-Server() {
    Log-Debug "miniserve --color-scheme squirrel --qrcode --upload-files[-u]" $Args
    miniserve --color-scheme squirrel --qrcode $Args
}
function Hugo-Server() {
    Log-Debug "hugo --config hugo.yml --watch --buildDrafts --forceSyncStatic --panicOnWarning server"
    hugo --config hugo.yml --watch --buildDrafts --forceSyncStatic --panicOnWarning server
}
function Idea-Open {
    param (
        [Parameter(Mandatory = $TRUE)]
        [string] $Path = $(throw "Path param is null!")
    )
    if (Directory-Exists-And-Is-Directory -Path $Path) {
        Log-Debug "idea64 $Path".ToLower()
        idea64 $Path
    }
}
################################
# powershell ip functions
################################

function set-ip() {
    # show all ethernet interfaces
    netsh interface ipv4 show interfaces

    $defaultIdx=1
    $idx = Read-Host-With-Default -Prompt "select interface idx" -DefaultValue $defaultIdx

    # show selected ethernet interface address
    netsh interface ipv4 show address name=$idx

    # set dhcp
    $dhcp = Read-Host-With-Default -Prompt "set source=[dhcp|static]" -DefaultValue 'static'

    if ('dhcp' -ieq $dhcp) {
        netsh interface ipv4 set address name=$idx source=dhcp

        Write-host "show interface $idx current address" -ForegroundColor Green
        netsh interface ipv4 show address name=$idx
        return
    }

    $defaultIP = '192.168.100.2'
    $ip = Read-Host-With-Default -Prompt 'set ip' -DefaultValue $defaultIP

    $defaultMask = '255.255.255.0'
    $mask = Read-Host-With-Default -Prompt 'set mask' -DefaultValue $defaultMask

    $defaultGateway = $defaultIP.Substring(0, $defaultIP.LastIndexOf('.')) + '.1'
    $gateway = Read-Host-With-Default -Prompt 'set gateway' -DefaultValue $defaultGateway

    netsh interface ipv4 set address name=$idx source=static address=$ip mask=$mask gateway=$gateway
    Write-host "netsh interface ipv4 show address name=$idx" -ForegroundColor Green
    netsh interface ipv4 show address name=$idx
}

function IP-Port-Forward-Add (
    [int] $port,
    [string] $ip
) {
    Log-Debug "netsh interface portproxy add v4tov4 listenport=$port connectaddress=$ip connectport=$port"
    netsh interface portproxy add v4tov4 listenport=$port connectaddress=$ip connectport=$port
}

function IP-Port-Forward-Delete (
    [int] $port
) {
    Log-Debug "netsh interface portproxy delete v4tov4 listenport=$port"
    netsh interface portproxy delete v4tov4 listenport=$port
}


function IP-Port-Forward-Show (
) {
    Log-Debug "netsh interface portproxy show all"
    netsh interface portproxy show all
}
function Java-Arthas() {
    # https://arthas.gitee.io/install-detail.html
    Log-Debug "java -jar $ENV:JAVA_HOME\arthas-boot.jar --repo-mirror aliyun --use-http $ARGS"
    java -jar $ENV:JAVA_HOME\arthas-boot.jar --repo-mirror aliyun --use-http $ARGS
}

function Java-Set-Jdk {
    param (
        [ValidateSet('8', '11', '17', '19',"12")]
        [string] $Version
    )
    $BasePath = 'd:\_app\_java'
    $JdkPath = $BasePath + $Version

    $CurrentJdkPath = (Get-Item -Path $BasePath).Target
    Log-Info "current jdk path : $CurrentJdkPath"

    if ($JdkPath.Equals($CurrentJdkPath)) {
        Log-Warn "not need change"
    }
    else {
        Log-Warn "Remove-Item $BasePath -Force -Confirm:$False"
        Remove-Item $BasePath -Force -Confirm:$False

        Log-Info "New-Item -ItemType Junction -Path $BasePath -Target $JdkPath | Out-Null"
        New-Item -ItemType Junction -Path $BasePath -Target $JdkPath | Out-Null
    }

    Log-Debug "now jdk path : $((Get-Item -Path $BasePath).Target)"
}

# https://github.com/mziyabo/PSKubectlCompletion
function Kubernetes-ImportPSKubectlCompletion () {
    Import-Module -Name PSKubectlCompletion
    Register-KubectlCompletion
}

function Kubernetes-InstallPSKubectlCompletion () {
    Install-Module PSKubectlCompletion
}

function Kubernetes-GetTerminatedPod() {
    kubectl get pods -o custom-columns-file=D:\_code\blog\src\k8s\kubectl\terminated-pod.txt --sort-by='{status.containerStatuses[0].lastState.terminated.finishedAt}' $Args
}
function Log-Warn() {
    Write-Host $Args -ForegroundColor Yellow
}

function Log-Debug() {
    Write-Host $Args -ForegroundColor Green
}

function Log-Info() {
    Write-Host $Args -ForegroundColor Gray
}
################################
# powershell profile functions
################################

function script:Profile-New(
    [string] $ProfilePath = $(throw "ProfilePath is null!")
) {
    if (Test-Path $ProfilePath) {
        Log-Info "# $ProfilePath already existed."
    }
    else {
        New-Item -Path $Profile -ItemType File -Force
        Log-Debug "# Create [$ProfilePath] succeed."
    }
}

function Profile-AddScriptExpression (
    [string] $ProfilePath = $(throw "ProfilePath is null!"),
    [string] $ScriptExpression = $(throw "ScriptExpression is null!")
) {
    Profile-New -ProfilePath $ProfilePath

    $ProfileContent = Get-Content -Path $ProfilePath
    if ($ProfileContent -contains $ScriptExpression) {
        Log-Info "# [$ScriptExpression] already existed in $ProfilePath."
    }
    else {
        Set-Content -Path $ProfilePath -Value "$ProfileContent`r`n$ScriptExpression"
        Log-Debug "# [$ScriptExpression] append to $ProfilePath."
    }
}

function Profile-AddScriptFile (
    [string] $ProfilePath = $(throw "ProfilePath is null!"),
    [string] $ScriptFilePath = $(throw "ScriptFilePath is null!")
) {
    if (!(Test-Path $ScriptFilePath)) {
        throw "$ScriptFilePath not found."
    }

    Profile-AddScriptExpression -ProfilePath $ProfilePath -ScriptExpression ". ""$ScriptFilePath"""
}
################################
# powershell prompt functions
################################

function prompt () {
    # hold last exit code
    $OLD_LASTEXITCODE = $LASTEXITCODE

    $Now = [System.DateTimeOffset]::Now
    $DateTime = $Now.ToString('yy-MM-dd HH:mm:ss K')
    $DayOfWeek = [System.Int32]$Now.DayOfWeek
    $Week = $DayOfWeek.Equals(0)?7:$DayOfWeek
    $DayOfYear = $Now.DayOfYear
    $UnixTimeMilliseconds = $Now.ToUnixTimeMilliseconds()
    $UserPrompt = UI-GetUserPrompt
    $UserPromptPrefix = $UserPrompt.Prefix
    $UserPromptText = $UserPrompt.Text

    Write-Host -NoNewline "`n$UserPromptText $DateTime $UnixTimeMilliseconds w$Week d$DayOfYear" -ForegroundColor Gray
    if ($OLD_LASTEXITCODE -gt 0) {
        Write-Host -NoNewline " $OLD_LASTEXITCODE" -ForegroundColor Red
    }

    # if working directory is git repository
    if (Get-GitStatus) {

        # get git user.name and user.email
        $GitUser = Git-GetCurrentUser

        # show git user.name and user.email
        Write-Host -NoNewline "`n$UserPromptPrefix $GitUser :" -ForegroundColor Gray

        # show git status
        Write-VcsStatus
    }

    Write-Host

    # show current work directory in window title
    $Host.UI.RawUI.WindowTitle = $UserPromptText

    # reset last exit code
    $LASTEXITCODE = $OLD_LASTEXITCODE

    return "$UserPromptPrefix "
}
########################################
# powershell open visual studio sln file
########################################

function script:Sln-GetFiles() {
    $currentPath = Get-Location
    Log-Debug 'current path : ' $currentPath

    $slnFiles = Get-ChildItem -Path $currentPath -File -Filter *.sln

    return $slnFiles
}

function script:Sln-SelectFile($slnFiles) {
    if ($slnFiles.Count -eq 0) {
        throw 'sln file not found.'
    }

    if ($slnFiles.Count -eq 1) {
        return $slnFiles[0]
    }

    [int]$i = 0
    $slnFiles | ForEach-Object {
        Write-Host $i ': ' $_.Name
        $i++
    }

    [int]$index = Read-Host 'find more sln file, please input index (default 0) :'
    return $slnFiles[$index]
}

function Sln() {
    $slnFiles = Sln-GetFiles
    $slnFile = Sln-SelectFile $slnFiles
    Log-Debug 'opening...   : ' $slnFile
    Invoke-Item $slnFile
}
################################
# powershell ui functions
################################

function script:Test-Administrator {  
    $CurrentUser = [Security.Principal.WindowsIdentity]::GetCurrent();
    $CurrentPrincipal = New-Object Security.Principal.WindowsPrincipal $CurrentUser;
    return $CurrentPrincipal.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)  
}

function script:UI-GetUserName() {
    $UserName = $ENV:USERNAME.ToLower();
    if($UserName -eq 'administrator'){
        return 'admin';
    }
    return $UserName;
}

function script:UI-GetComputerName() {
    return $ENV:COMPUTERNAME.ToLower();
}

function UI-GetUserPrompt() {
    $Role = '$';
    $UserName = UI-GetUserName
    $ComputerName = UI-GetComputerName
    $CurrentPath = $(Get-Location).ToString().ToLower();
    if (Test-Administrator) {
        $Role = '#'
    }

    return @{
        Prefix       = $Role;
        UserName     = $UserName;
        ComputerName = $ComputerName;
        Text         = "$Role $UserName@$ComputerName $CurrentPath"
    }
}

function UI-SetDisplayOptions () {
    $Host.UI.RawUI.WindowPosition.X = 0;
    $Host.UI.RawUI.WindowPosition.Y = 0;

    $Host.UI.RawUI.BufferSize.Width = 80;
    $Host.UI.RawUI.BufferSize.Height = 2000;

    $Host.UI.RawUI.WindowSize.Width = 80;
    $Host.UI.RawUI.WindowSize.Height = 40;

    $Host.UI.RawUI.MaxWindowSize.Width = 80;
    $Host.UI.RawUI.MaxWindowSize.Height = 40;

    $Host.UI.RawUI.ForegroundColor = "White";
    $Host.UI.RawUI.BackgroundColor = "Black";
}
################################
# powershell vm(hyper-v) functions
################################

function vm ([string] $name) {
    if ([String]::IsNullOrEmpty($name)) {
        Get-VM
    }
    else {
        Get-VM -Name $name
    }
}

# https://docs.microsoft.com/en-us/powershell/module/hyper-v/new-vhd?view=win10-ps
function vhd-create(
    [string] $Path,
    [uint64] $Size = 128GB
) {
    Log-Debug "New-VHD -Path $Path -Dynamic -SizeBytes $Size"
    New-VHD `
        -Path $Path `
    -Dynamic `
        -SizeBytes $Size
}

# https://docs.microsoft.com/en-us/powershell/module/hyper-v/new-vm?view=win10-ps
# https://docs.microsoft.com/en-us/powershell/module/hyper-v/set-vm?view=win10-ps
# https://docs.microsoft.com/en-us/powershell/module/hyper-v/set-vmdvddrive?view=win10-ps
function vm-create(
    [string] $VMName,
    [string] $Path = 'e:\.vm',
    [string] $ISO
) {

    Log-Debug "New-VM -Name $VMName -Path $Path -Generation 1 -SwitchName 'HVS' -NewVHDPath "$Path\$VMName\disk.vhdx" -NewVHDSizeBytes 128GB"
    New-VM `
        -Name $VMName `
        -Path $Path `
        -Generation 1 `
        -SwitchName 'HVS' `
        -NewVHDPath "$Path\$VMName\disk.vhdx" `
        -NewVHDSizeBytes 128GB

    Log-Debug "Set-VMProcessor -VMName $VMName -Count 2"
    Set-VMProcessor `
        -VMName $VMName `
        -Count 2

    Log-Debug "Set-VMMemory -VMName $VMName -DynamicMemoryEnabled $TRUE -StartupBytes 1GB -MinimumBytes 1GB -MaximumBytes 4GB"
    Set-VMMemory `
        -VMName $VMName `
        -DynamicMemoryEnabled $TRUE `
        -StartupBytes 1GB `
        -MinimumBytes 1GB `
        -MaximumBytes 4GB

    if ($ISO) {
        Log-Debug "Set-VMDvdDrive -VMName $VMName -Path $ISO"
        Set-VMDvdDrive `
            -VMName $VMName `
            -Path $ISO
    }

    Log-Debug "Set-VM -Name $VMName -AutomaticStartAction 'Nothing' -AutomaticStopAction 'ShutDown' -CheckpointType 'Disabled'"
    Set-VM `
        -Name $VMName `
        -AutomaticStartAction 'Nothing' `
        -AutomaticStopAction 'ShutDown' `
        -CheckpointType 'Disabled'
}

function vm-run ([string] $name) {
    Get-VM -Name $name | Start-VM
}

function vm-stop ([string] $name) {
    Get-VM -Name $name | Stop-VM
}

function vm-ssh (
    [string]$username,
    [string]$hostname,
    [string]$port = 22) {

    Log-Debug "run [$hostname] hyper-v vm"
    vm-run -name $hostname

    Log-Debug "ssh $username@$hostname -p $port"
    ssh "$username@$hostname" -p $port
}

function ubt1 () {
    vm-ssh -username root -hostname ubt1
}

function ubt2 () {
    vm-ssh -username root -hostname ubt2
}

function ubt3 () {
    vm-ssh -username root -hostname ubt3
}

function ceos () {
    vm-ssh -username root -hostname ceos
}
function VsCode-Open {
    param (
        [Parameter(Mandatory = $TRUE)]
        [string] $Path = $(throw "Path param is null!")
    )
    if (Directory-Exists-And-Is-Directory -Path $Path) {
        Log-Debug "code $Path".ToLower()
        code $Path
    }
}
function WLAN-Export {
    Log-Debug "netsh wlan export profile key=clear"
    netsh wlan export profile key=clear
}
# https://github.com/jeremyfa/yaml.js
# cnpm install -yamljs -g

function Yaml-ToJson() {
    Log-Debug "yaml2json --pretty --indentation 2" $Args

    yaml2json --pretty --indentation 2 $Args
}

function Yaml-FromJson() {
    Log-Debug "json2yaml --depth 64 --indentation 2" $Args

    json2yaml --depth 64 --indentation 2 $Args
}
上一篇 : [PowerShell] Help
下一篇 : [PowerShell] Hyper-V