PSClassToolsBD09.psm1

function Install-VsCodeAndGit {
  <#
  .SYNOPSIS
    This command installd Git and VSCode into the AZ040 labs
  .DESCRIPTION
    This command will locate the lastest versions of Git and VSCode
    and install them silently, without any user input. It also sets
    the font size to 16 and the tab sie to two spaces in the VSCode
    settings file
  .PARAMETER GitFullName
    This is the name that will be set in the Git global config
  .PARAMETER GitEmailAddress
    This is the email address that will be set in the Git global config
  .EXAMPLE
    Install-VsCodeAndGit -GitFullName "John Dowe" -GitEmailAddress "JDowe@hotmail.com"
    This command downloads the git and vscode installer files into the temp directory
    and then installs these applications in VERYSILENT mode. It also sets up the
    Git Config file and sets default values for VSCode
  .NOTES
    General notes
      Created By: Brent Denny
      Created On: 01-Mar-2022
      Last Modified: 01-Mar-2022
    ChangeLog
      v1.0.0 Created the tools
      V1.0.1 Fixed a problem where the temp drive path was not working
      v1.0.5 Added Git config edits
      v1.1.0 Fixed an issue with the web content object different in PS7
             Added debug break points
      v1.1.5 Most issues fixed, added verbose troubleshooting points
      v1.1.8 Fixed a syntax problem that showed outerhtml on screen while the code was running
      V1.1.9 Changed the module and function names to better reflect the purpose
      v1.2.0 Added Code to wait until Git is completely installed before editing the config file
  #>

  [cmdletbinding()]
  Param (
    [Parameter(Mandatory=$true)]
    [string]$GitFullName,
    [Parameter(Mandatory=$true)]
    [string]$GitEmailAddress        
  )
  
  # Create WebClient object to be able to download files from the internet
  $WebClientObj = New-Object -TypeName System.Net.WebClient 
  if (Test-Path $env:TEMP) {$TempDrive = ($env:TEMP).Trim('\') + '\' }
  else {throw ('No temp drive to store downloads')}
  # get the contents of the git download website to discover the latest git version
  $GitWebContent = Invoke-WebRequest -Uri 'https://git-scm.com/download/win'
  Write-Verbose "Web content retrieved"
  Write-Debug "Web content retrieved"
  if ($PSVersionTable.PSVersion.Major -le 5) {
    $LatestGitRef = $GitWebContent.Links | Where-Object {$_.InnerHTML -like "*64*bit*windows*setup*"}
  }
  elseif ($PSVersionTable.PSVersion.Major -ge 6) {
    $LatestGitRef = $GitWebContent.Links | Where-Object {$_ -match '64.*bit.*Windows.*Setup'}
  }
  $LatestGitLink = $LatestGitRef.href
  $LatestGitFileName = Split-Path $LatestGitLink -Leaf
  $GitFileNamePath = $TempDrive + $LatestGitFileName
  Write-Verbose "Just before deploying Git"
  Write-Debug "Just before deploying Git"
  Write-Progress -Activity 'Deploying Git' -CurrentOperation 'Downloading Git' -PercentComplete  0
  #Download latest Git file
  $WebClientObj.DownloadFile($LatestGitLink,$GitFileNamePath)
  Invoke-Expression -Command "$GitFileNamePath /VERYSILENT /NORESTART" 
  $Percent = 0
  do {
    Write-Progress   -Activity 'Deploying Git' -CurrentOperation 'Installing Git' -PercentComplete $Percent
    Start-Sleep -Milliseconds 400
    $Percent++ 
  } until ($Percent -ge 100)
  $env:Path = "$env:Path;C:\Program Files\Git\cmd"
  $GitConfigFile = "c:\Program Files\Git\etc\gitconfig"
  do {
    $GitFileExists = $false
    if (Test-Path $GitConfigFile) {$GitFileExists -eq $true}
    if ($GitFileExists) {$GitFileInfo = Get-ChildItem $GitConfigFile}
    Start-Sleep -Seconds 1
  } Until ($GitFileExists -eq $true -and $GitFileInfo.Length -gt 200)
  # Modify Git config
  Write-Verbose "Just before Git config"
  Write-Debug "Just before Git config"
  git config --global user.name $GitFullName
  git config --global user.email $GitEmailAddress
  $GitConfigFile = "c:\Program Files\Git\etc\gitconfig"
  $OldGitConf = Get-Content $GitConfigFile
  $NewGitConf = $OldGitConf -replace 'defaultBranch = \b.+\b','defaultBranch = main'
  Set-Content -Path $GitConfigFile -Value $NewGitConf
  Write-Verbose "Just before deploying VSCode"
  Write-Debug "Just before deploying VSCode"
  # Deploying VSCode
  $Percent = 0
  $VSCodeLink = 'https://code.visualstudio.com/sha/download?build=stable&os=win32-x64-user'
  $VSCodeFileNamePath = $TempDrive + 'VSCodeSetup.exe'
  Write-Progress -Activity 'Deploying VSCode' -CurrentOperation 'Downloading VSCode' -PercentComplete  0
  $WebClientObj.DownloadFile($VSCodeLink,$VSCodeFileNamePath)
  Invoke-Expression -Command "$VSCodeFileNamePath /VERYSILENT /NORESTART" 
  do {
    Write-Progress   -Activity 'Deploying VSCode' -CurrentOperation 'Installing VSCode' -PercentComplete $Percent
    Start-Sleep -Milliseconds 400
    $Percent++ 
  } until ($Percent -ge 100)
  Write-Verbose "Just before killing Code.exe process"
  Write-Debug "Just before killing Code.exe process"
  Do {
    Start-Sleep -Milliseconds 100
    $CodeProc = Get-Process | Where-Object {$_.Name -eq 'Code'}
  } until ($CodeProc.Count -ge 1)
  Stop-Process -Name Code -Force -Confirm:$false
  Write-Verbose "Just before changing VSCode config"
  Write-Debug "Just before changing VSCode config"
  #Creating the VSCode settings file
  $VSCodeSettingsObj = [PSCustomObject]@{
    "security.workspace.trust.untrustedFiles"= "open"
    "editor.fontSize"= 16
    "debug.console.fontSize"= 16
    "markdown.preview.fontSize"= 16
    "terminal.integrated.fontSize"= 16
    "editor.tabSize"= 2
  }
  Set-Content -Path "$env:APPDATA\Code\User\settings.json" -Value ($VSCodeSettingsObj | ConvertTo-Json)
}