Initialize-PC.ps1

<#PSScriptInfo
.VERSION 1.10
.GUID c7e4c2a6-c3a3-45af-b82a-01d0a2ca28c1
.AUTHOR Dave Farinelli
.LICENSEURI https://www.gnu.org/licenses/gpl-3.0.en.html
.PROJECTURI https://github.com/dfar-io/initialize-pc
#>


<#
.DESCRIPTION
 Run this script to set up a new Windows PC. This script is safe to run multiple
 times to allow for reconfiguration.
#>


#Requires -RunAsAdministrator

Param(
    [switch] $SkipPrompts
)

function InitializeStartMenu {
    Write-Output 'Disabling Cortana...'
    $path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search"
    IF (!(Test-Path -Path $path)) {
        New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows" `
            -Name "Windows Search"
    }
    Set-ItemProperty -Path $path -Name "AllowCortana" -Value 0

    Write-Output 'Disabling Search Button...'
    $path = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Search"
    IF (!(Test-Path -Path $path)) {
        New-Item -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion" `
            -Name "Search"
    }
    Set-ItemProperty -Path $path -Name "SearchboxTaskbarMode" -Value 0

    Write-Output 'Disabling Task View Button...'
    $path = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"
    IF (!(Test-Path -Path $path)) {
        New-Item -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer" `
            -Name "Advanced"
    }
    Set-ItemProperty -Path $path -Name "ShowTaskViewButton" -Value 0

    Write-Output 'Disabling People Button...'
    $path = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\People"
    IF (!(Test-Path -Path $path)) {
        New-Item -Path "HKCU:\Microsoft\Windows\CurrentVersion\Explorer\Advanced"  `
            -Name "People"
    }
    Set-ItemProperty -Path $path -Name "PeopleBand" -Value 0

    #Restart Explorer to change it immediately
    Stop-Process -name explorer
}

function InstallChocolatey {
    try {
        choco -v | Out-Null
        Write-Output 'Chocolatey already installed.'
        return
    }
    catch {
        Write-Output 'Installing Chocolatey...'
        Set-ExecutionPolicy Bypass -Scope Process -Force; `
            &((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
    }
}

function InstallSoftwareWithChocolatey {
    Write-Output 'Installing Software with Chocolatey...'
    choco install -y `
        greenshot `
        googlechrome `
        divvy `
        7zip `
        ccleaner `
        dropbox `
        filezilla `
        git `
        nodejs `
        libreoffice-fresh `
        vscode `
        rescuetime `
        bitnami-xampp `
        mysql.workbench `
        postman `
        qbittorrent `
        sql-server-management-studio `
        teamviewer `
        visualstudio2017community `
        azure-cli `
        franz `
        intellijidea-community `
        psscriptanalyzer
}

function InstallAdditionalSoftware {
    if (IsSoftwareAlreadyInstalled("OpenVPN Connect")) {
        Write-Output "OpenVPN Connect already installed."
        return;
    }

    Write-Output 'Installing OpenVPN Connect...'
    Invoke-WebRequest `
        -Uri "https://swupdate.openvpn.net/as/clients/openvpn-connect-2.7.1.101_signed.msi" `
        -OutFile "install.msi"
    Start-Process install.msi -Wait
    Remove-Item install.msi

    Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
    WaitForPrompt("Install WSL")
}

function IsSoftwareAlreadyInstalled($name) {
    $x86 = ((Get-ChildItem "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall") |
        Where-Object { $_.GetValue( "DisplayName" ) -like "*$name*" } ).Length -gt 0;

    $x64 = ((Get-ChildItem "HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall") |
        Where-Object { $_.GetValue( "DisplayName" ) -like "*$name*" } ).Length -gt 0;

    return $x86 -or $x64;
}

function InvokeWindowsUpdate {
    if ($SkipPrompts) {
        Write-Output "Skipping updating Windows."
        return
    }

    WaitForPrompt("Update Windows")
}

function RemoveClutter {
    Write-Output "Deleting Windows Appx packages..."
    DeleteAppxPackage("windowsalarms")
    DeleteAppxPackage("getstarted")
    DeleteAppxPackage("zunemusic")
    DeleteAppxPackage("windowsapps")
    DeleteAppxPackage("solitarecollection")
    DeleteAppxPackage("bingnews")
    DeleteAppxPackage("onenote")
    DeleteAppxPackage("windowsphone")
    DeleteAppxPackage("weather")
    DeleteAppxPackage("DellInc.DellSupportAssistforPCs")
    DeleteAppxPackage("DellInc.DellDigitalDelivery")
    DeleteAppxPackage("DellInc.DellCommandUpdate")
    DeleteAppxPackage("WindowsFeedbackHub")
    DeleteAppxPackage("Microsoft.Office.Desktop")
    DeleteAppxPackage("ScreenSketch")
    DeleteAppxPackage("StickyNotes")
    DeleteAppxPackage("YourPhone")
    DeleteAppxPackage("GetHelp")
    DeleteAppxPackage("MobilePlans")
    DeleteAppxPackage("MixedReality")
    DeleteAppxPackage("LinkedIn")
    DeleteAppxPackage("Microsoft3DViewer")
    DeleteAppxPackage("WindowsMaps")
    DeleteAppxPackage("Microsoft.Messaging")
    UninstallOneDrive
}

function UninstallOneDrive {
    Write-Output "Uninstalling OneDrive..."
    taskkill /f /im OneDrive.exe | Out-Null
    C:\WINDOWS\SysWOW64\OneDriveSetup.exe /uninstall
}

function UninstallApplication($name) {
    $app = Get-CimInstance -Class Win32_Product `
        -Filter "Name = '$name'"

    if ($null -eq $app) {
        Write-Output "$name not found, no need to uninstall."
        return
    }
    else {
        $app.Uninstall()
    }
}

function DeleteAppxPackage($packageName) {
    Write-Output "Removing $packageName appx package."
    Get-AppxPackage *$packageName* | Remove-AppxPackage
}

function ImportStartMenu {
    if ($SkipPrompts) {
        Write-Output "Skipping importing Start Menu."
        return;
    }

    WaitForPrompt("Clean up the start menu of all tiles")
    WaitForPrompt("Unpin all items")
}

function WaitForPrompt($prompt) {
    do {
        $value = Read-Host "$prompt ('y' to continue)"
    }
    while ($value -notmatch 'y')
}

function InitializeSoftware {
    if ($SkipPrompts) {
        Write-Output "Skipping configuration of software."
        return;
    }

    WaitForPrompt("OpenVPN - Add all VPN servers")
    WaitForPrompt("Mail - add accounts, create linked inbox, turn off email notifications, signature, calendar on Monday")
    WaitForPrompt("Chrome - sign in")
    WaitForPrompt("Divvy - register, start at Login, hide from tray, set shortcut")
    WaitForPrompt("Dropbox - sign in, change to simple directory")
    WaitForPrompt("VSCode - install FiraCode")
    WaitForPrompt("VSCode - Perform Settings Sync (Shift-Alt-D)")
    WaitForPrompt("Greenshot - Increase icon size to 32, set output, remove magnifier")
    WaitForPrompt("PowerShell - Increase font size, use Fira Code")
    WaitForPrompt("Franz - Login")
    WaitForPrompt("CCleaner - Add /pictures, /download (clear after 24 hours), Save all settings to INI file.")
}

function InitializeCCleanerTask {
    $taskName = "Automatically Run CCleaner"
    $taskExists = Get-ScheduledTask | Where-Object { $_.TaskName -like $taskName }

    if ($taskExists) {
        Write-Output "CCleaner Task already exists, recreating...";
        Unregister-ScheduledTask -TaskName $taskName -Confirm:$false
    }

    Write-Output "Creating CCleaner Task..."
    $action = New-ScheduledTaskAction -Execute 'C:\Program Files\CCleaner\CCleaner.exe' `
        -Argument '/AUTO'

    $scheduledTimes = @(
        '12am', '1am', '2am', '3am', '4am', '5am', '6am', '7am', '8am', '9am',
        '10am', '11am', '12pm', '1pm', '2pm', '3pm', '4pm', '5pm', '6pm', '7pm',
        '8pm', '9pm', '10pm', '11pm'
    )
    $triggers = @()

    Foreach ($time in $scheduledTimes) {
        $triggers += New-ScheduledTaskTrigger -Daily -At $time
    }

    Register-ScheduledTask -Action $action -Trigger $triggers -TaskName $taskName `
        -Description "Run CCleaner Automatically" | Out-Null
}

function SetTimeZone {
    Write-Output "Setting Time Zone..."
    tzutil /s "Eastern Standard Time"
}

function SetPowershellProfile {
    Write-Output "Setting PowerShell profile..."
    New-Item -Path $Profile -Type File -Force | Out-Null
    Write-Output "Set-Location C:/" | Out-File $Profile
}

function InitializeGit {
    Write-Output "Configuring git..."
    git config --global user.name "Dave Farinelli"
    git config --global user.email "d@dfar.io"
}

function ClearDesktop {
    Write-Output 'Deleting desktop icons...'
    Remove-Item C:\Users\*\Desktop\*lnk -Force
}

################################################################################

SetTimeZone
InitializeStartMenu
RemoveClutter
ImportStartMenu
InvokeWindowsUpdate
InstallChocolatey
InstallSoftwareWithChocolatey
InstallAdditionalSoftware
InitializeSoftware
InitializeCCleanerTask
InvokeWindowsUpdate
SetPowershellProfile
InitializeGit
ClearDesktop