ninja-one/add-location-default-printers.ps1

#Requires -Version 5.1

<#
.SYNOPSIS
    Adds an IP printer as an "All User Printer" based on device location in NinjaOne.
#>


[CmdletBinding()]
param (
    [Parameter()]
    [switch]$RetryAttempt = $false
)

begin {
    # Check for required PowerShell version (7+)
    if (!($PSVersionTable.PSVersion.Major -ge 7)) {
        try {
            # Install PowerShell 7 if missing
            if (!(Test-Path "$env:SystemDrive\Program Files\PowerShell\7")) {
                Write-Output '[INFO] Installing PowerShell version 7...'
                Invoke-Expression "& { $( Invoke-RestMethod https://aka.ms/install-powershell.ps1 ) } -UseMSI -Quiet"
            }
        
            # Refresh PATH
            $env:Path = [System.Environment]::GetEnvironmentVariable('Path', 'Machine') + ';' + [System.Environment]::GetEnvironmentVariable('Path', 'User')
        
            # Restart script in PowerShell 7
            pwsh -File "`"$PSCommandPath`"" @PSBoundParameters
        
        }
        catch {
            Write-Output '[ERROR] PowerShell 7 was not installed. Update PowerShell and try again.'
            throw $Error
        }
        finally {
            exit $LASTEXITCODE
        }
    }
    else {
        $PSStyle.OutputRendering = 'PlainText'
    }    

    $tempDir = Join-Path $env:TEMP "JRE-Ninja\printers"
    if (-not (Test-Path $tempDir)) {
        New-Item -ItemType Directory -Path $tempDir -Force | Out-Null
    }

    # Define printer objects by location
    $MTP_Printers = @(
        @{
            PrinterName  = "Downstairs Media 4053"
            Hostname     = "DS-Media-4053"
            PrinterModel = "Kyocera CS 4053ci KX"
        },
        @{
            PrinterName  = "Downstairs Media 307"
            Hostname     = "DS-Media-307"
            PrinterModel = "Kyocera CS 307ci KX"
        },
        @{
            PrinterName  = "Upstairs Media 4053"
            Hostname     = "US-Media-4053"
            PrinterModel = "Kyocera CS 4053ci KX"
        },
        @{
            PrinterName  = "Safety Conference Room 307"
            Hostname     = "US-Conf-307"
            PrinterModel = "Kyocera CS 307ci KX"
        },
        @{
            PrinterName  = "Color Plotter Canon TX3000"
            Hostname     = "TX-3000ipd9de71"
            PrinterModel = "Canon TX3000"
        },
        @{
            PrinterName  = "BW Plotter PlotWave 365"
            Hostname     = "mtpplot"
            PrinterModel = "Oce PlotWave 365 - WPD2"
        }
    )
    
    $Clio_Printers = @(
        @{
            PrinterName  = "Clio 4053"
            Hostname     = "Clio-4053"
            PrinterModel = "Kyocera CS 4053ci KX"
        }
    )
    
    $SSM_Printers = @(
        @{
            PrinterName  = "SSM 4053"
            Hostname     = "SSM-4053"
            PrinterModel = "Kyocera CS 4053ci KX"
        }
    )
    
    $CL_Printers = @(
    )

    function Install-AzModule {
        # check if Az.Storage module is installed
        if (-not (Get-Module -ListAvailable -Name Az.Storage)) {
            Write-Host "Installing Az.Storage module..."

            # check to make sure the PSGallery is registered
            if (-not (Get-PSRepository -Name PSGallery -ErrorAction SilentlyContinue)) {
                Write-Host "Registering PSGallery repository..."
                Register-PSRepository -Default
            }

            Install-Module -Name Az.Storage -Repository PSGallery -Scope CurrentUser -Force -AllowClobber

            # Refresh PATH
            $env:Path = [System.Environment]::GetEnvironmentVariable('Path', 'Machine') + ';' + [System.Environment]::GetEnvironmentVariable('Path', 'User')
        
            if (!$RetryAttempt) {
                # Restart script in PowerShell 7
                Write-Host "RESTARTING SCRIPT IN POWERSHELL 7"
                $NewParams = @{}
                # Copy all bound parameters except RetryAttempt
                foreach ($key in $PSBoundParameters.Keys) {
                    if ($key -ne 'RetryAttempt') {
                        $NewParams[$key] = $PSBoundParameters[$key]
                    }
                }
                # Add RetryAttempt parameter with value $true
                $NewParams['RetryAttempt'] = $true
                pwsh -File $PSCommandPath @NewParams
            }
        }
        else {
            Write-Host "Az.Storage module is already installed"
        }
        # Import the module
        Import-Module -Name Az.Storage -Force -ErrorAction Stop
        Write-Host "Az.Storage module imported successfully"
    }

    function Get-ScriptFile {
        param (
            [Parameter(Mandatory = $true)]
            [string]$File
        )
        $accountname = "jreappstorage"
        $containername = "it-dept"
        $token = Ninja-Property-Get itDeptBlobRead
        $azureContext = New-AzStorageContext -StorageAccountName $accountname -SasToken $token

        $filePath = Join-Path $tempDir (Split-Path $File -leaf)

        Write-Host "Downloading fresh copy from $accountname/$containername/$File..."
        Remove-Item -Path $filePath -Force -ErrorAction SilentlyContinue
        
        try {
            Get-AzStorageBlobContent -Container $containername -Blob $File -Destination $filePath -Context $azureContext -Force | Out-Null
            Write-Host "File downloaded successfully to $filePath"
        }
        catch {
            throw "Failed to download file: $_"
        }

        return $filePath
    }
}
process {
    try {
        # Possible values are MTP, Clio, SSM, CL
        $DeviceLocation = $env:NINJA_LOCATION_NAME

        # Add printers based on device location
        switch ($DeviceLocation) {
            "MTP" {
                $Printers = $MTP_Printers
            }
            "Clio" {
                $Printers = $Clio_Printers
            }
            "SSM" {
                $Printers = $SSM_Printers
            }
            "Centerline" {
                $Printers = $CL_Printers
            }
            "Field" {
                Write-Error "[WARNING] No printers for device location: $DeviceLocation"
                exit 1
            }
            default {
                Write-Error "[ERROR] Unknown device location: $DeviceLocation"
                exit 1
            }
        }

        if (-not $Printers -or $Printers.Count -eq 0) {
            Write-Error "[ERROR] No printers defined for location: $DeviceLocation"
            exit 1
        }

        Install-AzModule

        # Get the script file from Azure Storage
        $scriptFile = Get-ScriptFile -File "scripts/ninja-one/add-ip-printer.ps1"

        # Add printers to the system
        foreach ($Printer in $Printers) {
            # Add the printer using the script from Azure Storage
            & $scriptFile -PrinterName $Printer.PrinterName -Hostname $Printer.Hostname -PrinterModel $Printer.PrinterModel -Remove:$false
        }


    }
    catch {
        Write-Error "[ERROR] Failed to add network printers: $_"
        # Write the line number
        
        $ErrorLine = $_.InvocationInfo.ScriptLineNumber
        Write-Error "[ERROR] Line Number: $ErrorLine"
        exit 1
    }
    exit 0
}
end {


}