Skip to content

Instantly share code, notes, and snippets.

@cubytz
Created November 14, 2025 00:45
Show Gist options
  • Select an option

  • Save cubytz/47b61c01df24f4202bcd9ba01ee2e5ce to your computer and use it in GitHub Desktop.

Select an option

Save cubytz/47b61c01df24f4202bcd9ba01ee2e5ce to your computer and use it in GitHub Desktop.

Revisions

  1. cubytz created this gist Nov 14, 2025.
    1,408 changes: 1,408 additions & 0 deletions setup.ps1
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,1408 @@
    # Interactive Machine Setup Script with Main Menu

    # Printer Installation Function
    function Install-NetworkPrinter {
    param(
    [string]$PrinterName,
    [string]$PrinterIP,
    [bool]$SetAsDefault = $false
    )

    Write-Host "Installing printer: $PrinterName" -ForegroundColor Cyan

    try {
    # Create port name
    $portName = "IP_$PrinterIP"

    # Check if port already exists
    $portExists = Get-PrinterPort -Name $portName -ErrorAction SilentlyContinue

    if (-not $portExists) {
    Write-Host " Creating printer port..." -ForegroundColor Gray
    Add-PrinterPort -Name $portName -PrinterHostAddress $PrinterIP -ErrorAction Stop
    } else {
    Write-Host " Printer port already exists" -ForegroundColor Gray
    }

    # Try to auto-detect and install printer driver
    Write-Host " Attempting to auto-detect printer..." -ForegroundColor Gray

    # Add the printer using the port
    try {
    Add-Printer -Name $PrinterName -PortName $portName -ErrorAction Stop
    Write-Host " ✓ Printer installed with auto-detected driver" -ForegroundColor Green
    } catch {
    # If auto-detection fails, try with generic driver
    Write-Host " Auto-detection failed, trying with generic driver..." -ForegroundColor Yellow

    # Use generic PostScript or PCL driver
    $genericDriver = Get-PrinterDriver -Name "*PS*" -ErrorAction SilentlyContinue | Select-Object -First 1

    if (-not $genericDriver) {
    $genericDriver = Get-PrinterDriver -Name "*PCL*" -ErrorAction SilentlyContinue | Select-Object -First 1
    }

    if ($genericDriver) {
    Add-Printer -Name $PrinterName -DriverName $genericDriver.Name -PortName $portName -ErrorAction Stop
    Write-Host " ✓ Printer installed with generic driver: $($genericDriver.Name)" -ForegroundColor Green
    } else {
    throw "No suitable driver found. Please install manually."
    }
    }

    # Set as default if requested
    if ($SetAsDefault) {
    Write-Host " Setting as default printer..." -ForegroundColor Gray
    $printer = Get-Printer -Name $PrinterName -ErrorAction Stop
    Set-Printer -Name $PrinterName -ErrorAction Stop
    (New-Object -ComObject WScript.Network).SetDefaultPrinter($PrinterName)
    Write-Host " ✓ Set as default printer" -ForegroundColor Green
    }

    Write-Host " ✓ Printer '$PrinterName' installed successfully" -ForegroundColor Green
    Write-Host " IP: $PrinterIP" -ForegroundColor Gray

    return $true

    } catch {
    Write-Warning " ✗ Failed to install printer '$PrinterName': $_"
    Write-Host " You may need to install the printer driver manually" -ForegroundColor Yellow
    return $false
    }
    }

    # Function to create user account
    function Create-UserAccount {
    Write-Host ""
    Write-Host "=== Create User Account ===" -ForegroundColor Yellow

    Write-Host "Enter Username:" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $UserName = Read-Host

    Write-Host "Enter Password:" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $UserPassword = Read-Host -AsSecureString
    $UserPasswordPlain = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($UserPassword))

    Write-Host "Make this user an Administrator? (Y/N):" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $MakeAdmin = Read-Host
    $IsAdministrator = ($MakeAdmin -eq "Y" -or $MakeAdmin -eq "y")

    try {
    $SecurePassword = ConvertTo-SecureString $UserPasswordPlain -AsPlainText -Force
    New-LocalUser -Name $UserName -Password $SecurePassword -Description "$(if($IsAdministrator){'Administrator account'}else{'Standard user account'})" -ErrorAction Stop

    if ($IsAdministrator) {
    Add-LocalGroupMember -Group "Administrators" -Member $UserName -ErrorAction Stop
    Write-Host "✓ Administrator account '$UserName' created successfully" -ForegroundColor Green
    } else {
    Add-LocalGroupMember -Group "Users" -Member $UserName -ErrorAction Stop
    Write-Host "✓ Standard user account '$UserName' created successfully" -ForegroundColor Green
    }
    } catch {
    Write-Warning "Failed to create user account: $_"
    }

    Write-Host ""
    Write-Host "Press any key to return to main menu..." -ForegroundColor Gray
    $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
    }

    # Function to install software
    function Install-Software {
    Write-Host ""
    Write-Host "=== Install Software ===" -ForegroundColor Yellow
    Write-Host "Select software to install (separate numbers with spaces, e.g., 1 2 3):" -ForegroundColor Yellow
    Write-Host "1. Google Chrome"
    Write-Host "2. Mozilla Firefox"
    Write-Host "3. VLC Media Player"
    Write-Host "4. 7-Zip"
    Write-Host "5. Notepad++"
    Write-Host "6. Adobe Acrobat"
    Write-Host "7. Microsoft Office"
    Write-Host "8. RustDesk (Remote Desktop)"
    Write-Host "9. Dropbox"
    Write-Host "10. 1Password"
    Write-Host "11. Docker Desktop"
    Write-Host "12. TeamViewer"
    Write-Host "13. All of the above"
    Write-Host "14. Cancel"
    Write-Host "Enter your choices:" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $SoftwareChoice = Read-Host

    $SoftwareList = @()

    if ($SoftwareChoice -match "\b13\b") {
    $SoftwareList = @("Google.Chrome", "Mozilla.Firefox", "VideoLAN.VLC", "7zip.7zip", "Notepad++.Notepad++", "Adobe.Acrobat.DC", "Microsoft.Office", "RustDesk.RustDesk", "Dropbox.Dropbox", "AgileBits.1Password", "Docker.DockerDesktop", "TeamViewer.TeamViewer")
    } elseif ($SoftwareChoice -notmatch "\b14\b") {
    if ($SoftwareChoice -match "\b1\b") { $SoftwareList += "Google.Chrome" }
    if ($SoftwareChoice -match "\b2\b") { $SoftwareList += "Mozilla.Firefox" }
    if ($SoftwareChoice -match "\b3\b") { $SoftwareList += "VideoLAN.VLC" }
    if ($SoftwareChoice -match "\b4\b") { $SoftwareList += "7zip.7zip" }
    if ($SoftwareChoice -match "\b5\b") { $SoftwareList += "Notepad++.Notepad++" }
    if ($SoftwareChoice -match "\b6\b") { $SoftwareList += "Adobe.Acrobat.DC" }
    if ($SoftwareChoice -match "\b7\b") { $SoftwareList += "Microsoft.Office" }
    if ($SoftwareChoice -match "\b8\b") { $SoftwareList += "RustDesk.RustDesk" }
    if ($SoftwareChoice -match "\b9\b") { $SoftwareList += "Dropbox.Dropbox" }
    if ($SoftwareChoice -match "\b10\b") { $SoftwareList += "AgileBits.1Password" }
    if ($SoftwareChoice -match "\b11\b") { $SoftwareList += "Docker.DockerDesktop" }
    if ($SoftwareChoice -match "\b12\b") { $SoftwareList += "TeamViewer.TeamViewer" }
    }

    if ($SoftwareList.Count -gt 0) {
    Write-Host ""
    Write-Host "Installing software packages..." -ForegroundColor Yellow
    foreach ($app in $SoftwareList) {
    Write-Host "Installing: $app" -ForegroundColor Cyan
    try {
    winget install --silent --accept-package-agreements --accept-source-agreements $app
    Write-Host "$app installed" -ForegroundColor Green
    } catch {
    Write-Warning " ✗ Failed to install $app : $_"
    }
    }
    Write-Host ""
    Write-Host "✓ Software installation complete!" -ForegroundColor Green
    }

    Write-Host ""
    Write-Host "Press any key to return to main menu..." -ForegroundColor Gray
    $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
    }

    # Function to configure network printers
    function Configure-NetworkPrinters {
    Write-Host ""
    Write-Host "=== Configure Network Printers ===" -ForegroundColor Yellow

    $continuePrinters = $true

    while ($continuePrinters) {
    Write-Host ""
    Write-Host "1. Add a network printer"
    Write-Host "2. View installed printers"
    Write-Host "3. Remove a printer"
    Write-Host "4. Return to main menu"
    Write-Host ""
    Write-Host "Select option:" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $printerChoice = Read-Host

    switch ($printerChoice) {
    "1" {
    Write-Host ""
    Write-Host "--- Add Network Printer ---" -ForegroundColor Yellow

    Write-Host "Enter printer name (e.g., Office Printer):" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $PrinterName = Read-Host

    Write-Host "Enter printer IP address (e.g., 192.168.1.100):" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $PrinterIP = Read-Host

    Write-Host "Set as default printer? (Y/N):" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $SetDefault = Read-Host

    $setAsDefault = ($SetDefault -eq "Y" -or $SetDefault -eq "y")
    Install-NetworkPrinter -PrinterName $PrinterName -PrinterIP $PrinterIP -SetAsDefault $setAsDefault
    }
    "2" {
    Write-Host ""
    Write-Host "--- Installed Printers ---" -ForegroundColor Yellow
    $printers = Get-Printer | Select-Object Name, DriverName, PortName
    if ($printers.Count -gt 0) {
    foreach ($printer in $printers) {
    Write-Host "$($printer.Name)" -ForegroundColor Cyan
    Write-Host " Driver: $($printer.DriverName)" -ForegroundColor Gray
    Write-Host " Port: $($printer.PortName)" -ForegroundColor Gray
    }
    } else {
    Write-Host "No printers installed." -ForegroundColor Gray
    }
    }
    "3" {
    Write-Host ""
    Write-Host "--- Remove Printer ---" -ForegroundColor Yellow
    $printers = Get-Printer
    if ($printers.Count -gt 0) {
    for ($i = 0; $i -lt $printers.Count; $i++) {
    Write-Host " $($i + 1). $($printers[$i].Name)" -ForegroundColor Cyan
    }
    Write-Host ""
    Write-Host "Enter printer number to remove (or 0 to cancel):" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $removeIndex = Read-Host

    $removeNum = [int]$removeIndex
    if ($removeNum -gt 0 -and $removeNum -le $printers.Count) {
    $printerToRemove = $printers[$removeNum - 1]
    try {
    Remove-Printer -Name $printerToRemove.Name -ErrorAction Stop
    Write-Host "✓ Printer '$($printerToRemove.Name)' removed successfully" -ForegroundColor Green
    } catch {
    Write-Warning "Failed to remove printer: $_"
    }
    } elseif ($removeNum -ne 0) {
    Write-Host "Invalid selection." -ForegroundColor Red
    }
    } else {
    Write-Host "No printers to remove." -ForegroundColor Gray
    }
    }
    "4" {
    $continuePrinters = $false
    }
    default {
    Write-Host "Invalid option. Please select 1-4." -ForegroundColor Red
    }
    }
    }
    }

    # Function to configure network shares
    function Configure-NetworkShares {
    Write-Host ""
    Write-Host "=== Configure Network Shares ===" -ForegroundColor Yellow

    $continueShares = $true

    while ($continueShares) {
    Write-Host ""
    Write-Host "1. Create a new network share"
    Write-Host "2. View existing shares"
    Write-Host "3. Remove a share"
    Write-Host "4. Return to main menu"
    Write-Host ""
    Write-Host "Select option:" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $shareChoice = Read-Host

    switch ($shareChoice) {
    "1" {
    Write-Host ""
    Write-Host "--- Create Network Share ---" -ForegroundColor Yellow

    Write-Host "Enter share name (e.g., SharedFiles):" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $ShareName = Read-Host

    Write-Host "Enter folder path (e.g., C:\Shares\SharedFiles):" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $FolderPath = Read-Host

    Write-Host "Enter share description (optional):" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $ShareDescription = Read-Host

    Write-Host "Access level - 1=Read Only, 2=Full Access, 3=Change:" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $AccessChoice = Read-Host

    try {
    # Create folder if it doesn't exist
    if (!(Test-Path -Path $FolderPath)) {
    New-Item -Path $FolderPath -ItemType Directory -Force | Out-Null
    Write-Host " Created folder: $FolderPath" -ForegroundColor Green
    }

    # Remove existing share if it exists
    $existingShare = Get-SmbShare -Name $ShareName -ErrorAction SilentlyContinue
    if ($existingShare) {
    Remove-SmbShare -Name $ShareName -Force
    Write-Host " Removed existing share with same name" -ForegroundColor Yellow
    }

    # Create the share
    $smbParams = @{
    Name = $ShareName
    Path = $FolderPath
    ErrorAction = 'Stop'
    }

    if ($ShareDescription) {
    $smbParams.Description = $ShareDescription
    }

    switch ($AccessChoice) {
    "1" {
    $smbParams.ReadAccess = "Everyone"
    $permission = "ReadAndExecute"
    }
    "3" {
    $smbParams.ChangeAccess = "Everyone"
    $permission = "Modify"
    }
    default {
    $smbParams.FullAccess = "Everyone"
    $permission = "FullControl"
    }
    }

    New-SmbShare @smbParams | Out-Null

    # Set NTFS permissions
    $acl = Get-Acl $FolderPath
    $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("Everyone", $permission, "ContainerInherit,ObjectInherit", "None", "Allow")
    $acl.SetAccessRule($accessRule)
    Set-Acl -Path $FolderPath -AclObject $acl

    Write-Host "✓ Share '$ShareName' created successfully" -ForegroundColor Green
    Write-Host " Network path: \\$env:COMPUTERNAME\$ShareName" -ForegroundColor Gray

    } catch {
    Write-Warning "Failed to create share: $_"
    }
    }
    "2" {
    Write-Host ""
    Write-Host "--- Existing Network Shares ---" -ForegroundColor Yellow
    $shares = Get-SmbShare | Where-Object { $_.Special -eq $false }
    if ($shares.Count -gt 0) {
    foreach ($share in $shares) {
    Write-Host "$($share.Name)" -ForegroundColor Cyan
    Write-Host " Path: $($share.Path)" -ForegroundColor Gray
    if ($share.Description) {
    Write-Host " Description: $($share.Description)" -ForegroundColor Gray
    }
    Write-Host " Network path: \\$env:COMPUTERNAME\$($share.Name)" -ForegroundColor Gray
    }
    } else {
    Write-Host "No custom shares found." -ForegroundColor Gray
    }
    }
    "3" {
    Write-Host ""
    Write-Host "--- Remove Network Share ---" -ForegroundColor Yellow
    $shares = Get-SmbShare | Where-Object { $_.Special -eq $false }
    if ($shares.Count -gt 0) {
    for ($i = 0; $i -lt $shares.Count; $i++) {
    Write-Host " $($i + 1). $($shares[$i].Name) - $($shares[$i].Path)" -ForegroundColor Cyan
    }
    Write-Host ""
    Write-Host "Enter share number to remove (or 0 to cancel):" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $removeIndex = Read-Host

    $removeNum = [int]$removeIndex
    if ($removeNum -gt 0 -and $removeNum -le $shares.Count) {
    $shareToRemove = $shares[$removeNum - 1]
    try {
    Remove-SmbShare -Name $shareToRemove.Name -Force -ErrorAction Stop
    Write-Host "✓ Share '$($shareToRemove.Name)' removed successfully" -ForegroundColor Green
    } catch {
    Write-Warning "Failed to remove share: $_"
    }
    } elseif ($removeNum -ne 0) {
    Write-Host "Invalid selection." -ForegroundColor Red
    }
    } else {
    Write-Host "No shares to remove." -ForegroundColor Gray
    }
    }
    "4" {
    $continueShares = $false
    }
    default {
    Write-Host "Invalid option. Please select 1-4." -ForegroundColor Red
    }
    }
    }
    }

    # Function to enable OpenSSH Server
    function Enable-OpenSSHServer {
    Write-Host ""
    Write-Host "=== Enable OpenSSH Server ===" -ForegroundColor Yellow

    try {
    # Check if OpenSSH Server is already installed
    $sshServer = Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH.Server*'

    if ($sshServer.State -eq "Installed") {
    Write-Host "OpenSSH Server is already installed." -ForegroundColor Green
    } else {
    Write-Host "Installing OpenSSH Server..." -ForegroundColor Yellow
    Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
    Write-Host "✓ OpenSSH Server installed successfully" -ForegroundColor Green
    }

    # Check if SSH service is running
    $sshService = Get-Service -Name sshd -ErrorAction SilentlyContinue
    if ($sshService.Status -ne "Running") {
    Write-Host "Starting OpenSSH Server service..." -ForegroundColor Yellow
    Start-Service sshd
    Write-Host "✓ OpenSSH Server service started" -ForegroundColor Green
    } else {
    Write-Host "OpenSSH Server service is already running." -ForegroundColor Green
    }

    # Ensure service is set to automatic startup
    if ($sshService.StartType -ne "Automatic") {
    Write-Host "Setting service to start automatically..." -ForegroundColor Yellow
    Set-Service -Name sshd -StartupType 'Automatic'
    Write-Host "✓ Service set to automatic startup" -ForegroundColor Green
    } else {
    Write-Host "Service is already set to automatic startup." -ForegroundColor Green
    }

    # Configure firewall rule
    Write-Host "Checking firewall configuration..." -ForegroundColor Yellow
    $firewallRule = Get-NetFirewallRule -Name "OpenSSH-Server-In-TCP" -ErrorAction SilentlyContinue
    if (!$firewallRule) {
    New-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
    Write-Host "✓ Firewall rule created" -ForegroundColor Green
    } else {
    Write-Host "✓ Firewall rule already exists" -ForegroundColor Green
    }

    # Check current default shell configuration
    Write-Host "Checking SSH default shell configuration..." -ForegroundColor Yellow
    $currentShell = Get-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -ErrorAction SilentlyContinue
    $powerShellPath = (Get-Command powershell.exe).Source

    if ($currentShell -and $currentShell.DefaultShell -eq $powerShellPath) {
    Write-Host "✓ PowerShell is already set as default SSH shell" -ForegroundColor Green
    } else {
    if ($currentShell) {
    Write-Host "Current default shell: $($currentShell.DefaultShell)" -ForegroundColor Gray
    } else {
    Write-Host "Current default shell: cmd.exe (Windows default)" -ForegroundColor Gray
    }

    Write-Host "Setting PowerShell as default SSH shell..." -ForegroundColor Yellow

    # Create the OpenSSH registry key if it doesn't exist
    if (!(Test-Path "HKLM:\SOFTWARE\OpenSSH")) {
    New-Item -Path "HKLM:\SOFTWARE\OpenSSH" -Force | Out-Null
    }

    New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value $powerShellPath -PropertyType String -Force | Out-Null
    Write-Host "✓ PowerShell set as default SSH shell" -ForegroundColor Green

    # Restart SSH service to apply changes
    Write-Host "Restarting SSH service to apply changes..." -ForegroundColor Yellow
    Restart-Service sshd -ErrorAction Stop
    Write-Host "✓ SSH service restarted" -ForegroundColor Green
    }

    Write-Host ""
    Write-Host "✓ OpenSSH Server setup complete!" -ForegroundColor Green
    Write-Host " Status: Running" -ForegroundColor Gray
    Write-Host " Startup: Automatic" -ForegroundColor Gray
    Write-Host " Default Shell: PowerShell" -ForegroundColor Gray
    Write-Host " Firewall: Configured" -ForegroundColor Gray
    Write-Host ""
    Write-Host " You can connect using: ssh $env:USERNAME@$env:COMPUTERNAME" -ForegroundColor Gray
    Write-Host " Note: SSH users in the Administrators group will have admin rights" -ForegroundColor Gray

    } catch {
    Write-Warning "Failed to enable OpenSSH Server: $_"
    }

    Write-Host ""
    Write-Host "Press any key to return to main menu..." -ForegroundColor Gray
    $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
    }

    # Function to install WSL
    function Install-WSL {
    Write-Host ""
    Write-Host "=== Install WSL (Windows Subsystem for Linux) ===" -ForegroundColor Yellow

    try {
    # Check if WSL is already installed
    $wslVersion = wsl --version 2>$null

    if ($LASTEXITCODE -eq 0) {
    Write-Host "WSL is already installed." -ForegroundColor Green
    Write-Host ""
    wsl --version
    Write-Host ""

    # List installed distributions
    Write-Host "Installed Linux distributions:" -ForegroundColor Yellow
    wsl --list --verbose

    Write-Host ""
    Write-Host "Would you like to install an additional distribution? (Y/N):" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $installDistro = Read-Host

    if ($installDistro -eq "Y" -or $installDistro -eq "y") {
    Write-Host ""
    Write-Host "Select a distribution to install:" -ForegroundColor Yellow
    Write-Host "1. Ubuntu (latest)"
    Write-Host "2. Ubuntu 22.04 LTS"
    Write-Host "3. Ubuntu 20.04 LTS"
    Write-Host "4. Debian"
    Write-Host "5. Kali Linux"
    Write-Host "6. openSUSE Leap"
    Write-Host "7. Cancel"
    Write-Host ""
    Write-Host "Enter your choice:" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $distroChoice = Read-Host

    $distroName = ""
    switch ($distroChoice) {
    "1" { $distroName = "Ubuntu" }
    "2" { $distroName = "Ubuntu-22.04" }
    "3" { $distroName = "Ubuntu-20.04" }
    "4" { $distroName = "Debian" }
    "5" { $distroName = "kali-linux" }
    "6" { $distroName = "openSUSE-Leap-15.5" }
    "7" {
    Write-Host "Cancelled." -ForegroundColor Yellow
    Write-Host ""
    Write-Host "Press any key to return to main menu..." -ForegroundColor Gray
    $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
    return
    }
    default {
    Write-Host "Invalid selection." -ForegroundColor Red
    Write-Host ""
    Write-Host "Press any key to return to main menu..." -ForegroundColor Gray
    $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
    return
    }
    }

    Write-Host ""
    Write-Host "Installing $distroName..." -ForegroundColor Yellow
    wsl --install -d $distroName
    Write-Host "$distroName installed successfully" -ForegroundColor Green
    Write-Host " You can launch it by typing: wsl -d $distroName" -ForegroundColor Gray
    }
    } else {
    # WSL is not installed
    Write-Host "WSL is not installed. Installing..." -ForegroundColor Yellow
    Write-Host ""
    Write-Host "Select a distribution to install:" -ForegroundColor Yellow
    Write-Host "1. Ubuntu (latest) - Recommended"
    Write-Host "2. Ubuntu 22.04 LTS"
    Write-Host "3. Ubuntu 20.04 LTS"
    Write-Host "4. Debian"
    Write-Host "5. Kali Linux"
    Write-Host "6. openSUSE Leap"
    Write-Host "7. Install WSL without a distribution"
    Write-Host ""
    Write-Host "Enter your choice:" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $distroChoice = Read-Host

    if ($distroChoice -eq "7") {
    Write-Host ""
    Write-Host "Installing WSL without distribution..." -ForegroundColor Yellow
    wsl --install --no-distribution
    Write-Host "✓ WSL installed successfully" -ForegroundColor Green
    Write-Host " You can install a distribution later using: wsl --install -d <DistroName>" -ForegroundColor Gray
    Write-Host " List available distributions: wsl --list --online" -ForegroundColor Gray
    } else {
    $distroName = ""
    switch ($distroChoice) {
    "1" { $distroName = "Ubuntu" }
    "2" { $distroName = "Ubuntu-22.04" }
    "3" { $distroName = "Ubuntu-20.04" }
    "4" { $distroName = "Debian" }
    "5" { $distroName = "kali-linux" }
    "6" { $distroName = "openSUSE-Leap-15.5" }
    default {
    Write-Host "Invalid selection. Installing WSL with default Ubuntu..." -ForegroundColor Yellow
    $distroName = "Ubuntu"
    }
    }

    Write-Host ""
    Write-Host "Installing WSL with $distroName..." -ForegroundColor Yellow
    Write-Host "This may take several minutes..." -ForegroundColor Gray
    wsl --install -d $distroName
    Write-Host "✓ WSL and $distroName installed successfully" -ForegroundColor Green
    }

    Write-Host ""
    Write-Host "IMPORTANT: A system restart is required to complete WSL installation." -ForegroundColor Yellow
    Write-Host "After restart, launch your Linux distribution to complete setup." -ForegroundColor Yellow
    }

    } catch {
    Write-Warning "Failed to install WSL: $_"
    Write-Host ""
    Write-Host "Note: WSL installation requires Windows 10 version 2004 or higher, or Windows 11." -ForegroundColor Yellow
    }

    Write-Host ""
    Write-Host "Press any key to return to main menu..." -ForegroundColor Gray
    $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
    }


    # Function for full setup
    function Full-Setup {
    Write-Host ""
    Write-Host "=== Full Machine Setup ===" -ForegroundColor Green
    Write-Host ""

    # Computer Name
    Write-Host "Enter Computer Name:" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $ComputerName = Read-Host

    # User Account
    Write-Host "Enter Username for new account:" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $UserName = Read-Host

    Write-Host "Enter Password for $UserName :" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $UserPassword = Read-Host -AsSecureString
    $UserPasswordPlain = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($UserPassword))

    # User Account Type
    Write-Host "Make $UserName an Administrator? (Y/N):" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $MakeAdmin = Read-Host
    $IsAdministrator = ($MakeAdmin -eq "Y" -or $MakeAdmin -eq "y")

    # Network Share Setup
    $NetworkShares = @()
    $continueShares = $true

    Write-Host "Configure network shares? (Y/N):" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $ConfigureShares = Read-Host

    if ($ConfigureShares -eq "Y" -or $ConfigureShares -eq "y") {
    while ($continueShares) {
    Write-Host ""
    Write-Host "=== Network Share Configuration Menu ===" -ForegroundColor Yellow
    Write-Host "1. Add a network share"
    Write-Host "2. Review configured shares"
    Write-Host "3. Remove a share from list"
    Write-Host "4. Continue with setup"
    Write-Host ""
    Write-Host "Select option:" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $shareMenuChoice = Read-Host

    switch ($shareMenuChoice) {
    "1" {
    # Add share
    Write-Host ""
    Write-Host "--- Add Network Share ---" -ForegroundColor Yellow

    Write-Host "Enter share name (e.g., SharedFiles):" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $ShareName = Read-Host

    Write-Host "Enter folder path (e.g., C:\Shares\SharedFiles):" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $FolderPath = Read-Host

    Write-Host "Enter share description (optional):" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $ShareDescription = Read-Host

    Write-Host "Access level - 1=Read Only, 2=Full Access, 3=Custom:" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $AccessChoice = Read-Host

    $AccessLevel = "Full"
    switch ($AccessChoice) {
    "1" { $AccessLevel = "Read" }
    "2" { $AccessLevel = "Full" }
    "3" { $AccessLevel = "Custom" }
    }

    $NetworkShares += @{
    Name = $ShareName
    Path = $FolderPath
    Description = $ShareDescription
    Access = $AccessLevel
    }

    Write-Host "✓ Share '$ShareName' added to configuration list" -ForegroundColor Green
    }
    "2" {
    # Review shares
    Write-Host ""
    if ($NetworkShares.Count -eq 0) {
    Write-Host "No shares configured yet." -ForegroundColor Yellow
    } else {
    Write-Host "--- Configured Shares ---" -ForegroundColor Yellow
    for ($i = 0; $i -lt $NetworkShares.Count; $i++) {
    $share = $NetworkShares[$i]
    Write-Host " $($i + 1). $($share.Name)" -ForegroundColor Cyan
    Write-Host " Path: $($share.Path)" -ForegroundColor Gray
    Write-Host " Access: $($share.Access)" -ForegroundColor Gray
    if ($share.Description) {
    Write-Host " Description: $($share.Description)" -ForegroundColor Gray
    }
    }
    }
    }
    "3" {
    # Remove share
    Write-Host ""
    if ($NetworkShares.Count -eq 0) {
    Write-Host "No shares to remove." -ForegroundColor Yellow
    } else {
    Write-Host "--- Remove Share ---" -ForegroundColor Yellow
    for ($i = 0; $i -lt $NetworkShares.Count; $i++) {
    Write-Host " $($i + 1). $($NetworkShares[$i].Name)" -ForegroundColor Cyan
    }
    Write-Host ""
    Write-Host "Enter share number to remove (or 0 to cancel):" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $removeIndex = Read-Host

    $removeNum = [int]$removeIndex
    if ($removeNum -gt 0 -and $removeNum -le $NetworkShares.Count) {
    $removedShare = $NetworkShares[$removeNum - 1]
    $NetworkShares = $NetworkShares | Where-Object { $_ -ne $removedShare }
    Write-Host "✓ Removed '$($removedShare.Name)' from configuration" -ForegroundColor Green
    } elseif ($removeNum -ne 0) {
    Write-Host "Invalid selection." -ForegroundColor Red
    }
    }
    }
    "4" {
    # Continue
    $continueShares = $false
    }
    default {
    Write-Host "Invalid option. Please select 1-4." -ForegroundColor Red
    }
    }
    }
    }

    # Network Printer Setup
    $NetworkPrinters = @()
    $continuePrinters = $true

    Write-Host "Configure network printers? (Y/N):" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $ConfigurePrinters = Read-Host

    if ($ConfigurePrinters -eq "Y" -or $ConfigurePrinters -eq "y") {
    while ($continuePrinters) {
    Write-Host ""
    Write-Host "=== Printer Configuration Menu ===" -ForegroundColor Yellow
    Write-Host "1. Add a network printer"
    Write-Host "2. Review configured printers"
    Write-Host "3. Remove a printer from list"
    Write-Host "4. Continue with setup"
    Write-Host ""
    Write-Host "Select option:" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $printerMenuChoice = Read-Host

    switch ($printerMenuChoice) {
    "1" {
    # Add printer
    Write-Host ""
    Write-Host "--- Add Network Printer ---" -ForegroundColor Yellow

    Write-Host "Enter printer name (e.g., Office Printer):" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $PrinterName = Read-Host

    Write-Host "Enter printer IP address or hostname (e.g., 192.168.1.100):" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $PrinterIP = Read-Host

    Write-Host "Set as default printer? (Y/N):" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $SetDefault = Read-Host

    $NetworkPrinters += @{
    Name = $PrinterName
    IP = $PrinterIP
    SetDefault = ($SetDefault -eq "Y" -or $SetDefault -eq "y")
    }

    Write-Host "✓ Printer '$PrinterName' added to configuration list" -ForegroundColor Green
    }
    "2" {
    # Review printers
    Write-Host ""
    if ($NetworkPrinters.Count -eq 0) {
    Write-Host "No printers configured yet." -ForegroundColor Yellow
    } else {
    Write-Host "--- Configured Printers ---" -ForegroundColor Yellow
    for ($i = 0; $i -lt $NetworkPrinters.Count; $i++) {
    $printer = $NetworkPrinters[$i]
    Write-Host " $($i + 1). $($printer.Name)" -ForegroundColor Cyan
    Write-Host " IP: $($printer.IP)" -ForegroundColor Gray
    Write-Host " Default: $(if($printer.SetDefault){'Yes'}else{'No'})" -ForegroundColor Gray
    }
    }
    }
    "3" {
    # Remove printer
    Write-Host ""
    if ($NetworkPrinters.Count -eq 0) {
    Write-Host "No printers to remove." -ForegroundColor Yellow
    } else {
    Write-Host "--- Remove Printer ---" -ForegroundColor Yellow
    for ($i = 0; $i -lt $NetworkPrinters.Count; $i++) {
    Write-Host " $($i + 1). $($NetworkPrinters[$i].Name)" -ForegroundColor Cyan
    }
    Write-Host ""
    Write-Host "Enter printer number to remove (or 0 to cancel):" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $removeIndex = Read-Host

    $removeNum = [int]$removeIndex
    if ($removeNum -gt 0 -and $removeNum -le $NetworkPrinters.Count) {
    $removedPrinter = $NetworkPrinters[$removeNum - 1]
    $NetworkPrinters = $NetworkPrinters | Where-Object { $_ -ne $removedPrinter }
    Write-Host "✓ Removed '$($removedPrinter.Name)' from configuration" -ForegroundColor Green
    } elseif ($removeNum -ne 0) {
    Write-Host "Invalid selection." -ForegroundColor Red
    }
    }
    }
    "4" {
    # Continue
    $continuePrinters = $false
    }
    default {
    Write-Host "Invalid option. Please select 1-4." -ForegroundColor Red
    }
    }
    }
    }

    # WiFi Setup
    Write-Host "Setup WiFi? (Y/N):" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $SetupWiFi = Read-Host

    $WiFiSSID = ""
    $WiFiPasswordPlain = ""
    $WiFiSecurity = "WPA2PSK"

    if ($SetupWiFi -eq "Y" -or $SetupWiFi -eq "y") {
    Write-Host "Enter WiFi SSID:" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $WiFiSSID = Read-Host

    Write-Host "Enter WiFi Password:" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $WiFiPassword = Read-Host -AsSecureString
    $WiFiPasswordPlain = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($WiFiPassword))

    Write-Host "WiFi Security Type (1=WPA2PSK, 2=WPA3PSK, 3=Open):" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $SecurityChoice = Read-Host

    switch ($SecurityChoice) {
    "2" { $WiFiSecurity = "WPA3PSK" }
    "3" { $WiFiSecurity = "Open" }
    default { $WiFiSecurity = "WPA2PSK" }
    }
    }

    # Static IP Configuration
    Write-Host "Configure static IP address? (Y/N):" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $ConfigureStaticIP = Read-Host

    $StaticIPConfig = $null

    if ($ConfigureStaticIP -eq "Y" -or $ConfigureStaticIP -eq "y") {
    Write-Host ""
    Write-Host "--- Static IP Configuration ---" -ForegroundColor Yellow

    # Get available network adapters
    $adapters = Get-NetAdapter | Where-Object { $_.Status -eq "Up" }

    if ($adapters.Count -eq 0) {
    Write-Warning "No active network adapters found. Static IP configuration will be skipped."
    } else {
    Write-Host "Available network adapters:" -ForegroundColor Yellow
    for ($i = 0; $i -lt $adapters.Count; $i++) {
    Write-Host " $($i + 1). $($adapters[$i].Name) - $($adapters[$i].InterfaceDescription)" -ForegroundColor Cyan
    }

    Write-Host "Select adapter number:" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $adapterChoice = Read-Host

    $adapterIndex = [int]$adapterChoice - 1
    if ($adapterIndex -ge 0 -and $adapterIndex -lt $adapters.Count) {
    $selectedAdapter = $adapters[$adapterIndex]

    Write-Host "Enter IP address (e.g., 192.168.1.100):" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $IPAddress = Read-Host

    Write-Host "Enter subnet mask prefix length (e.g., 24 for 255.255.255.0):" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $PrefixLength = Read-Host

    Write-Host "Enter default gateway (e.g., 192.168.1.1):" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $Gateway = Read-Host

    Write-Host "Enter primary DNS server (e.g., 8.8.8.8):" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $DNS1 = Read-Host

    Write-Host "Enter secondary DNS server (optional, press Enter to skip):" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $DNS2 = Read-Host

    $StaticIPConfig = @{
    AdapterName = $selectedAdapter.Name
    IPAddress = $IPAddress
    PrefixLength = $PrefixLength
    Gateway = $Gateway
    DNS1 = $DNS1
    DNS2 = $DNS2
    }

    Write-Host "✓ Static IP configuration saved" -ForegroundColor Green
    } else {
    Write-Warning "Invalid adapter selection. Static IP configuration skipped."
    }
    }
    }

    # Software Selection
    Write-Host ""
    Write-Host "Select software to install (separate numbers with spaces, e.g., 1 2 3):" -ForegroundColor Yellow
    Write-Host "1. Google Chrome"
    Write-Host "2. Mozilla Firefox"
    Write-Host "3. VLC Media Player"
    Write-Host "4. 7-Zip"
    Write-Host "5. Notepad++"
    Write-Host "6. Adobe Acrobat"
    Write-Host "7. Microsoft Office"
    Write-Host "8. RustDesk (Remote Desktop)"
    Write-Host "9. Dropbox"
    Write-Host "10. 1Password"
    Write-Host "11. Docker Desktop"
    Write-Host "12. TeamViewer"
    Write-Host "13. All of the above"
    Write-Host "14. None (skip software installation)"
    Write-Host "Enter your choices:" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $SoftwareChoice = Read-Host

    $SoftwareList = @()

    if ($SoftwareChoice -match "\b13\b") {
    $SoftwareList = @("Google.Chrome", "Mozilla.Firefox", "VideoLAN.VLC", "7zip.7zip", "Notepad++.Notepad++", "Adobe.Acrobat.DC", "Microsoft.Office", "RustDesk.RustDesk", "Dropbox.Dropbox", "AgileBits.1Password", "Docker.DockerDesktop", "TeamViewer.TeamViewer")
    } elseif ($SoftwareChoice -notmatch "\b14\b") {
    if ($SoftwareChoice -match "\b1\b") { $SoftwareList += "Google.Chrome" }
    if ($SoftwareChoice -match "\b2\b") { $SoftwareList += "Mozilla.Firefox" }
    if ($SoftwareChoice -match "\b3\b") { $SoftwareList += "VideoLAN.VLC" }
    if ($SoftwareChoice -match "\b4\b") { $SoftwareList += "7zip.7zip" }
    if ($SoftwareChoice -match "\b5\b") { $SoftwareList += "Notepad++.Notepad++" }
    if ($SoftwareChoice -match "\b6\b") { $SoftwareList += "Adobe.Acrobat.DC" }
    if ($SoftwareChoice -match "\b7\b") { $SoftwareList += "Microsoft.Office" }
    if ($SoftwareChoice -match "\b8\b") { $SoftwareList += "RustDesk.RustDesk" }
    if ($SoftwareChoice -match "\b9\b") { $SoftwareList += "Dropbox.Dropbox" }
    if ($SoftwareChoice -match "\b10\b") { $SoftwareList += "AgileBits.1Password" }
    if ($SoftwareChoice -match "\b11\b") { $SoftwareList += "Docker.DockerDesktop" }
    if ($SoftwareChoice -match "\b12\b") { $SoftwareList += "TeamViewer.TeamViewer" }
    }

    # Domain Join
    Write-Host "Join a domain? (Y/N):" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $JoinDomainChoice = Read-Host

    $JoinDomain = $false
    $DomainName = ""

    if ($JoinDomainChoice -eq "Y" -or $JoinDomainChoice -eq "y") {
    $JoinDomain = $true
    Write-Host "Enter Domain Name:" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $DomainName = Read-Host
    }

    # Summary
    Write-Host ""
    Write-Host "=== Setup Summary ===" -ForegroundColor Yellow
    Write-Host "Computer Name: $ComputerName"
    Write-Host "User Account: $UserName ($(if($IsAdministrator){'Administrator'}else{'Standard User'}))"
    if ($NetworkShares.Count -gt 0) {
    Write-Host "Network Shares: $($NetworkShares.Count) configured"
    }
    if ($NetworkPrinters.Count -gt 0) {
    Write-Host "Network Printers: $($NetworkPrinters.Count) configured"
    }
    Write-Host "WiFi SSID: $(if($WiFiSSID){$WiFiSSID}else{'Not configured'})"
    if ($StaticIPConfig) {
    Write-Host "Static IP: $($StaticIPConfig.IPAddress)/$($StaticIPConfig.PrefixLength) on $($StaticIPConfig.AdapterName)"
    }
    Write-Host "Software: $(if($SoftwareList.Count -gt 0){$SoftwareList.Count.ToString() + ' packages selected'}else{'None'})"
    Write-Host "Domain: $(if($JoinDomain){$DomainName}else{'Not joining'})"
    Write-Host ""
    Write-Host "Proceed with setup? (Y/N):" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $Confirm = Read-Host

    if ($Confirm -ne "Y" -and $Confirm -ne "y") {
    Write-Host "Setup cancelled." -ForegroundColor Red
    return
    }

    Write-Host ""
    Write-Host "=== Starting Setup ===" -ForegroundColor Green
    Write-Host ""

    # 1. Setup WiFi
    if ($WiFiSSID) {
    Write-Host "Setting up WiFi connection: $WiFiSSID" -ForegroundColor Yellow

    $WiFiProfileXml = @"
    <?xml version="1.0"?>
    <WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1">
    <name>$WiFiSSID</name>
    <SSIDConfig>
    <SSID>
    <name>$WiFiSSID</name>
    </SSID>
    </SSIDConfig>
    <connectionType>ESS</connectionType>
    <connectionMode>auto</connectionMode>
    <MSM>
    <security>
    <authEncryption>
    <authentication>$(if($WiFiSecurity -eq "Open"){"open"}else{"WPA2PSK"})</authentication>
    <encryption>$(if($WiFiSecurity -eq "Open"){"none"}else{"AES"})</encryption>
    <useOneX>false</useOneX>
    </authEncryption>
    $(if($WiFiSecurity -ne "Open"){
    "<sharedKey>
    <keyType>passPhrase</keyType>
    <protected>false</protected>
    <keyMaterial>$WiFiPasswordPlain</keyMaterial>
    </sharedKey>"
    })
    </security>
    </MSM>
    <MacRandomization xmlns="http://www.microsoft.com/networking/WLAN/profile/v3">
    <enableRandomization>false</enableRandomization>
    </MacRandomization>
    </WLANProfile>
    "@

    $TempProfile = "$env:TEMP\wifi_profile.xml"
    $WiFiProfileXml | Out-File -FilePath $TempProfile -Encoding UTF8

    try {
    netsh wlan add profile filename="$TempProfile" | Out-Null
    netsh wlan connect name="$WiFiSSID" | Out-Null
    Remove-Item $TempProfile -Force

    Write-Host "WiFi setup complete. Waiting for connection..." -ForegroundColor Green
    Start-Sleep -Seconds 5

    if (Test-NetConnection -ComputerName "8.8.8.8" -Port 53 -InformationLevel Quiet -WarningAction SilentlyContinue) {
    Write-Host "Internet connection established!" -ForegroundColor Green
    } else {
    Write-Warning "WiFi connected but no internet access detected"
    }

    } catch {
    Write-Warning "WiFi setup failed: $_"
    }
    }

    # 1b. Configure Static IP
    if ($StaticIPConfig) {
    Write-Host "Configuring static IP address..." -ForegroundColor Yellow

    try {
    $adapter = Get-NetAdapter -Name $StaticIPConfig.AdapterName -ErrorAction Stop

    # Remove existing IP configuration
    Write-Host " Removing existing IP configuration..." -ForegroundColor Gray
    Remove-NetIPAddress -InterfaceAlias $StaticIPConfig.AdapterName -Confirm:$false -ErrorAction SilentlyContinue
    Remove-NetRoute -InterfaceAlias $StaticIPConfig.AdapterName -Confirm:$false -ErrorAction SilentlyContinue

    # Set static IP address
    Write-Host " Setting IP address: $($StaticIPConfig.IPAddress)/$($StaticIPConfig.PrefixLength)" -ForegroundColor Gray
    New-NetIPAddress -InterfaceAlias $StaticIPConfig.AdapterName `
    -IPAddress $StaticIPConfig.IPAddress `
    -PrefixLength $StaticIPConfig.PrefixLength `
    -DefaultGateway $StaticIPConfig.Gateway `
    -ErrorAction Stop | Out-Null

    # Set DNS servers
    $dnsServers = @($StaticIPConfig.DNS1)
    if ($StaticIPConfig.DNS2) {
    $dnsServers += $StaticIPConfig.DNS2
    }

    Write-Host " Setting DNS servers: $($dnsServers -join ', ')" -ForegroundColor Gray
    Set-DnsClientServerAddress -InterfaceAlias $StaticIPConfig.AdapterName `
    -ServerAddresses $dnsServers `
    -ErrorAction Stop

    Write-Host " ✓ Static IP configured successfully" -ForegroundColor Green
    Write-Host " IP: $($StaticIPConfig.IPAddress)/$($StaticIPConfig.PrefixLength)" -ForegroundColor Gray
    Write-Host " Gateway: $($StaticIPConfig.Gateway)" -ForegroundColor Gray
    Write-Host " DNS: $($dnsServers -join ', ')" -ForegroundColor Gray

    # Test connectivity
    Start-Sleep -Seconds 3
    if (Test-NetConnection -ComputerName $StaticIPConfig.Gateway -InformationLevel Quiet -WarningAction SilentlyContinue) {
    Write-Host " ✓ Gateway is reachable" -ForegroundColor Green
    } else {
    Write-Warning " Gateway is not reachable. Please verify the configuration."
    }

    } catch {
    Write-Warning "Failed to configure static IP: $_"
    }
    }

    # 2. Rename computer
    Write-Host "Renaming computer to: $ComputerName" -ForegroundColor Yellow
    try {
    Rename-Computer -NewName $ComputerName -Force -ErrorAction Stop
    Write-Host "Computer renamed successfully" -ForegroundColor Green
    } catch {
    Write-Warning "Failed to rename computer: $_"
    }

    # 3. Create user account
    Write-Host "Creating user account: $UserName" -ForegroundColor Yellow
    try {
    $SecurePassword = ConvertTo-SecureString $UserPasswordPlain -AsPlainText -Force
    New-LocalUser -Name $UserName -Password $SecurePassword -Description "$(if($IsAdministrator){'Administrator account'}else{'Standard user account'})" -ErrorAction Stop

    if ($IsAdministrator) {
    Add-LocalGroupMember -Group "Administrators" -Member $UserName -ErrorAction Stop
    Write-Host "Administrator account created successfully" -ForegroundColor Green
    } else {
    Add-LocalGroupMember -Group "Users" -Member $UserName -ErrorAction Stop
    Write-Host "Standard user account created successfully" -ForegroundColor Green
    }
    } catch {
    Write-Warning "Failed to create user account: $_"
    }

    # 5. Create Network Shares
    if ($NetworkShares.Count -gt 0) {
    Write-Host "Creating network shares..." -ForegroundColor Yellow

    foreach ($share in $NetworkShares) {
    Write-Host "Setting up share: $($share.Name)" -ForegroundColor Cyan

    try {
    # Create folder if it doesn't exist
    if (!(Test-Path -Path $share.Path)) {
    New-Item -Path $share.Path -ItemType Directory -Force | Out-Null
    Write-Host " Created folder: $($share.Path)" -ForegroundColor Green
    }

    # Remove existing share if it exists
    $existingShare = Get-SmbShare -Name $share.Name -ErrorAction SilentlyContinue
    if ($existingShare) {
    Remove-SmbShare -Name $share.Name -Force
    Write-Host " Removed existing share" -ForegroundColor Yellow
    }

    # Create the share
    $smbParams = @{
    Name = $share.Name
    Path = $share.Path
    ErrorAction = 'Stop'
    }

    if ($share.Description) {
    $smbParams.Description = $share.Description
    }

    switch ($share.Access) {
    "Read" {
    $smbParams.ReadAccess = "Everyone"
    }
    "Full" {
    $smbParams.FullAccess = "Everyone"
    }
    "Custom" {
    # Change access is read + write but not delete
    $smbParams.ChangeAccess = "Everyone"
    }
    }

    New-SmbShare @smbParams | Out-Null

    # Set NTFS permissions on the folder
    $acl = Get-Acl $share.Path

    switch ($share.Access) {
    "Read" {
    $permission = "ReadAndExecute"
    }
    "Full" {
    $permission = "FullControl"
    }
    "Custom" {
    $permission = "Modify"
    }
    }

    $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("Everyone", $permission, "ContainerInherit,ObjectInherit", "None", "Allow")
    $acl.SetAccessRule($accessRule)
    Set-Acl -Path $share.Path -AclObject $acl

    Write-Host " ✓ Share '$($share.Name)' created successfully" -ForegroundColor Green
    Write-Host " Path: $($share.Path)" -ForegroundColor Gray
    Write-Host " Access: $($share.Access)" -ForegroundColor Gray
    Write-Host " Network path: \\$ComputerName\$($share.Name)" -ForegroundColor Gray

    } catch {
    Write-Warning " ✗ Failed to create share '$($share.Name)': $_"
    }
    }
    }

    # 6. Install Network Printers
    if ($NetworkPrinters.Count -gt 0) {
    Write-Host "Installing network printers..." -ForegroundColor Yellow

    foreach ($printer in $NetworkPrinters) {
    Install-NetworkPrinter -PrinterName $printer.Name -PrinterIP $printer.IP -SetAsDefault $printer.SetDefault
    }
    }

    # 7. Install software
    if ($SoftwareList.Count -gt 0) {
    Write-Host "Installing software packages..." -ForegroundColor Yellow
    foreach ($app in $SoftwareList) {
    Write-Host "Installing: $app" -ForegroundColor Cyan
    try {
    winget install --silent --accept-package-agreements --accept-source-agreements $app
    Write-Host "$app installed" -ForegroundColor Green
    } catch {
    Write-Warning " ✗ Failed to install $app : $_"
    }
    }
    }

    # 8. Domain join
    if ($JoinDomain -and $DomainName) {
    Write-Host "Joining domain: $DomainName" -ForegroundColor Yellow
    Write-Host "Enter domain admin credentials when prompted..." -ForegroundColor Cyan
    try {
    $Credential = Get-Credential -Message "Enter domain admin credentials for $DomainName"
    Add-Computer -DomainName $DomainName -Credential $Credential -ErrorAction Stop
    Write-Host "Domain join successful" -ForegroundColor Green
    } catch {
    Write-Warning "Domain join failed: $_"
    }
    }

    Write-Host ""
    Write-Host "=== Setup Complete! ===" -ForegroundColor Green
    Write-Host ""
    Write-Host "Summary:" -ForegroundColor Yellow
    Write-Host " • Computer renamed to: $ComputerName"
    Write-Host " • User created: $UserName ($(if($IsAdministrator){'Administrator'}else{'Standard User'}))"
    if ($NetworkShares.Count -gt 0) {
    Write-Host " • Network shares created: $($NetworkShares.Count)"
    foreach ($share in $NetworkShares) {
    Write-Host " - \\$ComputerName\$($share.Name) ($($share.Access) access)" -ForegroundColor Gray
    }
    }
    if ($NetworkPrinters.Count -gt 0) {
    Write-Host " • Network printers installed: $($NetworkPrinters.Count)"
    foreach ($printer in $NetworkPrinters) {
    Write-Host " - $($printer.Name) ($($printer.IP))$(if($printer.SetDefault){' [Default]'})" -ForegroundColor Gray
    }
    }
    if ($WiFiSSID) { Write-Host " • WiFi configured: $WiFiSSID" }
    if ($StaticIPConfig) {
    Write-Host " • Static IP configured: $($StaticIPConfig.IPAddress)/$($StaticIPConfig.PrefixLength)"
    Write-Host " - Adapter: $($StaticIPConfig.AdapterName)" -ForegroundColor Gray
    Write-Host " - Gateway: $($StaticIPConfig.Gateway)" -ForegroundColor Gray
    }
    if ($SoftwareList.Count -gt 0) {
    Write-Host " • Software installed: $($SoftwareList.Count) packages"
    }
    if ($JoinDomain) { Write-Host " • Joined domain: $DomainName" }
    Write-Host ""
    Write-Host "A restart is required to apply all changes." -ForegroundColor Yellow
    Write-Host "Restart now? (Y/N):" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $RestartChoice = Read-Host

    if ($RestartChoice -eq "Y" -or $RestartChoice -eq "y") {
    Write-Host "Restarting in 5 seconds..." -ForegroundColor Yellow
    Start-Sleep -Seconds 5
    Restart-Computer -Force
    } else {
    Write-Host "Please restart the computer manually to complete setup." -ForegroundColor Yellow
    }
    }

    # Main Menu Loop
    $continue = $true

    while ($continue) {
    Clear-Host
    Write-Host "======================================" -ForegroundColor Green
    Write-Host " Windows Machine Setup Script" -ForegroundColor Green
    Write-Host "======================================" -ForegroundColor Green
    Write-Host ""
    Write-Host "Select an option:" -ForegroundColor Yellow
    Write-Host "1. Full Machine Setup"
    Write-Host "2. Create User Account"
    Write-Host "3. Install Software"
    Write-Host "4. Configure Network Printers"
    Write-Host "5. Configure Network Shares"
    Write-Host "6. Enable OpenSSH Server"
    Write-Host "7. Install WSL (Windows Subsystem for Linux)"
    Write-Host "8. Exit"
    Write-Host ""
    Write-Host "Enter your choice (1-8):" -ForegroundColor Cyan -NoNewline
    Write-Host " " -NoNewline
    $choice = Read-Host

    switch ($choice) {
    "1" {
    Full-Setup
    }
    "2" {
    Create-UserAccount
    }
    "3" {
    Install-Software
    }
    "4" {
    Configure-NetworkPrinters
    }
    "5" {
    Configure-NetworkShares
    }
    "6" {
    Enable-OpenSSHServer
    }
    "7" {
    Install-WSL
    }
    "8" {
    Write-Host "Exiting script. Goodbye!" -ForegroundColor Green
    $continue = $false
    }
    default {
    Write-Host "Invalid selection. Please choose 1-8." -ForegroundColor Red
    Start-Sleep -Seconds 2
    }
    }
    }