ninja-one/ad-conversion.ps1

#Requires -Version 5.1

<#
.SYNOPSIS
    This script attempts to leave the current domain and join a workgroup using CIM methods. If CIM fails, it falls back to using netdom.
    It also clears specific registry values related to the last logged-in user.
    Finally, it installs a provisioning package.
#>


[CmdletBinding()]
param (
    [Parameter()]
    [string]$Token,
    [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'
    }
        
    if ($env:token -and $env:token -notlike "null") {
        $Token = Ninja-Property-Get $env:token
    }
    
    if (-not $Token) {
        Write-Host "Please specify a Token."
        exit 1
    }

    $tempDir = Join-Path $env:TEMP "JRE-Ninja"

    function Get-PPKGFile {
        $accountname = "jreappstorage"
        $containername = "it-dept"
        $file = "ninjaone/ProfWiz.ppkg"
        $azureContext = New-AzStorageContext -StorageAccountName $accountname -StorageAccountKey $Token

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

        Get-AzStorageBlobContent -Container $containername -Blob $file -Destination $filePath -Context $azureContext -Force | Out-Null

        # apply the provisioning package
        Write-Host "[INFO] Applying provisioning package..."
        Install-ProvisioningPackage -PackagePath $filePath -QuietInstall -ForceInstall -ErrorAction Stop

        Write-Host "[SUCCESS] Successfully applied provisioning package."  -ForegroundColor Green
    }

    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 Exit-AD {
        Write-Host "[INFO] Attempting to leave domain using CIM with local admin..."
        
        # Get the current computer system
        $computerSystem = Get-CimInstance -ClassName Win32_ComputerSystem
        
        # Check if we're on a domain
        if ($computerSystem.PartOfDomain) {
            Write-Host "Computer is currently part of domain: $($computerSystem.Domain)"
            
            # Using Invoke-CimMethod to call the UnjoinDomainOrWorkgroup method
            $result = Invoke-CimMethod -InputObject $computerSystem -MethodName UnjoinDomainOrWorkgroup -Arguments @{
                FUnjoinOptions = 0  # 0 means don't update domain account, 1 would update the account
            }
            
            if ($result.ReturnValue -eq 0) {
                Write-Host "[SUCCESS] Successfully unjoined from domain." -ForegroundColor Green
                
                # Now join a workgroup
                $result = Invoke-CimMethod -InputObject $computerSystem -MethodName JoinDomainOrWorkgroup -Arguments @{
                    Name = "WORKGROUP"
                }
                
                if ($result.ReturnValue -eq 0) {
                    Write-Host "[SUCCESS] Successfully joined WORKGROUP." -ForegroundColor Green
                }
                else {
                    Write-Host "[ERROR] Failed to join WORKGROUP. Return code: $($result.ReturnValue)"  -ForegroundColor Red
                    exit 1
                }
            }
            else {
                Write-Host "[ERROR] Failed to unjoin domain. Return code: $($result.ReturnValue)"  -ForegroundColor Red
                exit 1
            }
        }
        else {
            Write-Host "[INFO] Computer is not part of a domain. No action needed."
        }
    }

}
process {
    try {
        # Check if Az.Storage module is installed
        Install-AzModule
        
        # Create temp directory if it doesn't exist
        if (-not (Test-Path -Path $tempDir)) {
            New-Item -ItemType Directory -Path $tempDir | Out-Null
        }
        
        # Exit from AD domain and join workgroup
        Exit-AD

        # Get the provisioning package file
        Get-PPKGFile
        
        Write-Host "[SUCCESS] Successfully left the domain and applied provisioning package."  -ForegroundColor Green

        # Schedule a reboot after 15 seconds and then exit 0
        Write-Host "[INFO] Scheduling reboot in 15 seconds..."
        shutdown.exe /r /t 15 /c "Rebooting to apply changes." /f
        Write-Host "[INFO] Reboot scheduled. Exiting script."  -ForegroundColor Green
        exit 0

    }
    catch {
        Write-Host "[ERROR] Error: $_"  -ForegroundColor Red
        
        exit 1
    }

    exit 0
}
end {
}