private/Software/Install-GitForWindows.ps1
|
<#
.SYNOPSIS Installs Git for Windows and configures global Git identity. .DESCRIPTION Ensures Git for Windows is available by installing it with winget when needed, then configures global user.email and user.name values. If identity values are not provided as parameters, the function prompts interactively based on current git config values. .PARAMETER UserEmail The value to set for git global user.email. If omitted, the function prompts when required. .PARAMETER UserName The value to set for git global user.name. If omitted, the function prompts when required. .PARAMETER ForceIdentityUpdate Forces prompting for identity values even when existing global values are set. .OUTPUTS System.Management.Automation.PSCustomObject .EXAMPLE Install-GitForWindows Installs Git for Windows if not present and walks through interactive identity configuration. .EXAMPLE Install-GitForWindows -UserEmail 'you@example.com' -UserName 'Your Name' Installs Git for Windows if needed and sets global identity non-interactively. .EXAMPLE Install-GitForWindows -ForceIdentityUpdate Prompts for identity values even when user.email and user.name already exist. .NOTES Author: David Segura Company: Recast Software This function is supported only on Windows and requires winget. Change Summary: #> function Install-GitForWindows { [CmdletBinding(SupportsShouldProcess = $true)] [OutputType([pscustomobject])] param ( [Parameter()] [string]$UserEmail, [Parameter()] [string]$UserName, [Parameter()] [switch]$ForceIdentityUpdate, [Parameter()] [switch]$NonInteractive ) if (-not $IsWindows) { throw "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Install-GitForWindows is supported only on Windows." } $winget = Get-Command -Name 'winget' -ErrorAction SilentlyContinue if (-not $winget) { throw "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] winget is required but was not found. Install App Installer from Microsoft Store and try again." } $gitCommand = Get-Command -Name 'git' -ErrorAction SilentlyContinue $wasInstalled = $false if (-not $gitCommand) { if (-not $PSCmdlet.ShouldProcess('Git for Windows', 'Install with winget')) { return [pscustomobject]@{ GitVersion = $null WasInstalled = $false UserEmail = $null UserName = $null WingetCommand = $winget.Source } } Write-Host "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Git for Windows is not installed. Installing with winget..." -ForegroundColor DarkGray & $winget.Source install --id 'Git.Git' -e -h --accept-source-agreements --accept-package-agreements if ($LASTEXITCODE -ne 0) { throw "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Git for Windows installation failed with exit code $LASTEXITCODE." } Update-OSDeploySessionEnvironment $gitCommand = Get-Command -Name 'git' -ErrorAction SilentlyContinue if (-not $gitCommand) { $fallbackGitPath = Join-Path -Path ${env:ProgramFiles} -ChildPath 'Git\cmd\git.exe' if (Test-Path -Path $fallbackGitPath) { $gitCommand = Get-Command -Name $fallbackGitPath -ErrorAction SilentlyContinue } } if (-not $gitCommand) { throw "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Git was installed but git.exe was not found in PATH. Open a new PowerShell session and run the command again." } $wasInstalled = $true } else { $installedVersion = & $gitCommand.Source --version Write-Host "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Git is already installed: $installedVersion" -ForegroundColor Green } $currentEmail = ((& $gitCommand.Source config --global user.email 2>$null) -join '').Trim() $currentName = ((& $gitCommand.Source config --global user.name 2>$null) -join '').Trim() if ($WhatIfPreference) { $finalVersion = (& $gitCommand.Source --version).Trim() return [pscustomobject]@{ GitVersion = $finalVersion WasInstalled = $wasInstalled UserEmail = $currentEmail UserName = $currentName WingetCommand = $winget.Source } } if (-not $PSCmdlet.ShouldProcess('global Git identity', 'Configure user.email and user.name')) { $finalVersion = (& $gitCommand.Source --version).Trim() return [pscustomobject]@{ GitVersion = $finalVersion WasInstalled = $wasInstalled UserEmail = $currentEmail UserName = $currentName WingetCommand = $winget.Source } } if (-not $UserEmail) { if ([string]::IsNullOrWhiteSpace($currentEmail) -or $ForceIdentityUpdate) { $UserEmail = Read-Host 'Enter your Git email address' } elseif (-not $NonInteractive) { Write-Host "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Current git user.email: $currentEmail" -ForegroundColor DarkGray $changeEmail = Read-Host 'Do you want to change it? (y/n)' if ($changeEmail -match '^(y|yes)$') { $UserEmail = Read-Host 'Enter your new Git email address' } } else { Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] NonInteractive: keeping existing git user.email: $currentEmail" } } if (-not $UserName) { if ([string]::IsNullOrWhiteSpace($currentName) -or $ForceIdentityUpdate) { $UserName = Read-Host 'Enter your Git user name' } elseif (-not $NonInteractive) { Write-Host "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Current git user.name: $currentName" -ForegroundColor DarkGray $changeName = Read-Host 'Do you want to change it? (y/n)' if ($changeName -match '^(y|yes)$') { $UserName = Read-Host 'Enter your new Git user name' } } else { Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] NonInteractive: keeping existing git user.name: $currentName" } } if (-not [string]::IsNullOrWhiteSpace($UserEmail)) { if ($PSCmdlet.ShouldProcess('git global user.email', "Set to $UserEmail")) { & $gitCommand.Source config --global user.email "$UserEmail" Write-Host "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Set git user.email to $UserEmail" -ForegroundColor Green } } if (-not [string]::IsNullOrWhiteSpace($UserName)) { if ($PSCmdlet.ShouldProcess('git global user.name', "Set to $UserName")) { & $gitCommand.Source config --global user.name "$UserName" Write-Host "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Set git user.name to $UserName" -ForegroundColor Green } } $finalEmail = (& $gitCommand.Source config --global user.email).Trim() $finalName = (& $gitCommand.Source config --global user.name).Trim() $finalVersion = (& $gitCommand.Source --version).Trim() Write-Host "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] " Write-Host "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Your global Git identity is now:" -ForegroundColor Cyan Write-Host "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Name : $finalName" -ForegroundColor White Write-Host "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Email: $finalEmail" -ForegroundColor White [pscustomobject]@{ GitVersion = $finalVersion WasInstalled = $wasInstalled UserEmail = $finalEmail UserName = $finalName WingetCommand = $winget.Source } } |