KeycloakContainerConsole.psm1
function Export-Realm { #Stop container Write-Host "" $Script:stepCount = $Script:stepCount + 1 Write-Host "Step $Script:stepCount of $Script:totalSteps -->" -ForegroundColor DarkGray Stop-Container #Copy Realm File from container Write-Host "" $Script:stepCount = $Script:stepCount + 1 Write-Host "Step $Script:stepCount of $Script:totalSteps -->" -ForegroundColor DarkGray Write-Host "Copying realm file from container to local path..." $Script:realmExportPath = $Script:realmExportPath.TrimEnd("/") + "/NexusRealm-export.json" try{ docker cp keycloak:/NexusRealm-export.json $Script:realmExportPath Write-Host "Realm file copied to local path $Script:realmExportPath." } catch{ Write-Host "Could not copy file to local path $Script:realmExportPath." } Write-Host "" } function Get-ExportPath { #Prompt - Get path to Realm file or hit enter to use default file $RealmPathFailed = -1 while($RealmPathFailed -ne 0) { if($RealmPathFailed -eq 1) { Write-Host "!!! Invalid Path. Try again. !!!" } elseif($RealmPathFailed -eq 2) { Write-Host "!!! Folder only. Path should not have a file extension. Try again. !!!" } Write-Host "" $Script:realmExportPath = Read-Host '--> Provide the path to the folder you wish save the realm file (NexusRealm-export.json).' if($Script:realmExportPath -eq "") { $RealmPathFailed = 1 } elseif ($Script:realmExportPath -like '*.*') { $RealmPathFailed = 2 } elseif(Test-Path $Script:realmExportPath) { $RealmPathFailed = 0 } else { $RealmPathFailed = 1 } } } function Get-ImportFile { Write-Host "" $RealmPathFailed = -1 while($RealmPathFailed -ne 0) { if($RealmPathFailed -eq 1) { Write-Host "Invalid Path. Try again." Write-Host "" } if($RealmPathFailed -eq 2) { Write-Host "File should have a .json extension." Write-Host "" } $Script:realmExportPath = Read-Host '--> Provide the filepath to a realm file or hit enter to install the default.' if($Script:realmExportPath -eq "") { $Script:totalSteps = $Script:totalSteps + 2 $RealmPathFailed = 0 } elseif ($Script:realmExportPath -NotLike '*.json') { $RealmPathFailed = 2 } elseif(Test-Path $Script:realmExportPath) { $Script:totalSteps = $Script:totalSteps + 4 $RealmPathFailed = 0 } else { $RealmPathFailed = 1 } } } function Get-Realm { $Script:totalSteps = $Script:totalSteps + 3 #Start container if needed if($Script:containerStatus -eq 1){ Write-Host "" $Script:totalSteps = $Script:totalSteps + 1 $Script:stepCount = $Script:stepCount + 1 Write-Host "Step $Script:stepCount of $Script:totalSteps -->" -ForegroundColor DarkGray Start-Container Write-Host "" } # Export Realm File Write-Host "" $Script:stepCount = $Script:stepCount + 1 Write-Host "Step $Script:stepCount of $Script:totalSteps -->" -ForegroundColor DarkGray Write-Host "Exporting realm file from keycloak and saving as NexusRealm-export.json..." try{ cmd /C "docker exec -d keycloak c:/keycloak/keycloak-$($Script:tag)/bin/standalone.bat -Djboss.socket.binding.port-offset=100 -Dkeycloak.migration.action=export -Dkeycloak.migration.provider=singleFile -Dkeycloak.migration.realmName=NexusPortal -Dkeycloak.migration.usersExportStrategy=REALM_FILE -Dkeycloak.migration.file=c:/NexusRealm-export.json" #Write-Host "Exporting takes about 20 seconds..." Start-Sleep -Seconds 10 $ExportSucceeded = docker exec -i $Script:containerName powershell -c "test-path -d c:/NexusRealm-export.json" if($ExportSucceeded -eq "True"){ Write-Host "NexusRealm-export.json has been exported." } else { Read-Host "NexusRealm-export.json could not be exported." Write-Header Write-Status Write-Menu return } } catch { Write-Host "Export was unsuccessful." return } } function Get-Status { $Script:containerId = docker ps -qf "name=$Script:containerName" $Script:imageName = docker inspect --format='{{.Config.Image}}' $Script:containerName if ($Script:imageName -like "*11.0.1") { $Script:tag = "11.0.1" } elseif($Script:imageName -like "*8.0.2"){ $Script:tag = "8.0.2" } if ($Script:containerId) { $Script:containerStatus = 0; $Script:containerStatusString = "running "; return } $Script:containerId = docker ps -aqf "name=$Script:containerName" if ($Script:containerId) { $Script:containerStatus = 1; $Script:containerStatusString = "stopped "; return } $Script:containerId = '' $Script:containerStatus = 2 $Script:containerStatusString = "not found" return } function Get-Version { #Install Version 11.0.1 if($Script:tag -eq "11.0.1") { Write-Host "" $Script:stepCount = $Script:stepCount + 1 Write-Host "Step $Script:stepCount of $Script:totalSteps -->" -ForegroundColor DarkGray Write-Host "Installing Keycloak $($Script:tag)..." docker run --name keycloak -d -p 8080:8080 cogsdale/nexus-keycloak:v11.0.1 } #Install Version 8.0.2 elseif ($Script:tag -eq "8.0.2") { Write-Host "" $Script:stepCount = $Script:stepCount + 1 Write-Host "Step $Script:stepCount of $Script:totalSteps -->" -ForegroundColor DarkGray Write-Host "Installing Keycloak $($Script:tag)..." docker run --name keycloak -d -p 8080:8080 cogsdale/nexus-keycloak:v8.0.2 } Start-Sleep -Seconds 10 } function Import-Realm { #Copy Realm File to container if($Script:realmExportPath -ne "") { #Stop container Write-Host "" $Script:stepCount = $Script:stepCount + 1 Write-Host "Step $Script:stepCount of $Script:totalSteps -->" -ForegroundColor DarkGray Stop-Container #Copy Realm File to container Write-Host "" $Script:stepCount = $Script:stepCount + 1 Write-Host "Step $Script:stepCount of $Script:totalSteps -->" -ForegroundColor DarkGray Write-Host "Copy realm file from local path to container." docker cp $Script:realmExportPath keycloak:/NexusRealm-import.json Write-Host "Realm file copied to container $Script:containerName." #Start container Write-Host "" $Script:stepCount = $Script:stepCount + 1 Write-Host "Step $Script:stepCount of $Script:totalSteps -->" -ForegroundColor DarkGray Start-Container } } function Install-Container { Clear-Host Write-Host "****************************************************************************************************" Write-Host "** **" Write-Host "** Install Keycloak **" Write-Host "** **" Write-Host "****************************************************************************************************" $Script:stepCount = 0 $Script:totalSteps = 0 Install-Menu Get-Version Get-Status Set-Admin Import-Realm Submit-CLILogin New-Realm Write-Host "" Write-Host "Keycloak Install Complete." -ForegroundColor DarkGreen Write-Host "Open a browser and navigate to " -NoNewLine Write-Host "http://localhost:8080" -ForegroundColor DarkCyan -NoNewLine Write-Host " and login with admin user." Read-Host "--> Hit enter to continue..." } function Install-Menu { #Prompt User for Keycloak verions Write-Host "** **" Write-Host "** **" Write-Host "** a --- Keycloak v8.0.2 **" Write-Host "** b --- Keycloak v11.0.1 **" Write-Host "** **" Write-Host "** **" Write-Host "****************************************************************************************************" do{ $Version = Read-Host '--> Which version of Keycloak do you want to install?' } while($Version -notin "a", "b") #Install Version 11.0.1 if($Version -eq "b") { $Script:tag = "11.0.1" } #Install Version 8.0.2 elseif ($Version -eq "a") { $Script:tag = "8.0.2" } $Script:totalSteps = $Script:totalSteps + 1 Write-Host "" #Prompt User - Ask for an Admin user name do{ $Script:adminUser = Read-Host '--> Define an administrator user name.' } while($Script:adminUser -in "") #Prompt Password - Ask for an Admin password do{ $Script:adminPassword = Read-Host '--> Define an administrator password.' } while($Script:adminPassword -in "") $Script:totalSteps = $Script:totalSteps + 2 #Prompt - Get path to Realm file or hit enter to use default file if ($Script:realmExportPath -eq "") { Get-ImportFile } else { if($Script:realmExportPath -ne "") { $Script:totalSteps = $Script:totalSteps + 4 } else { $Script:totalSteps = $Script:totalSteps + 2 } } } function Install-Type { #Check if container is already running or stopped if($Script:containerStatus -in 0, 1){ if($Script:containerStatus -eq 0){ Write-Output "The container $Script:containerName is already running with ID: $Script:containerId"; } else { Write-Output "The container $Script:containerName exists but is currently stopped with ID: $Script:containerId"; } Write-Host "" do{ if($Script:containerStatus -eq 0){ $InstallYesNo = Read-Host '--> Do you want to replace the running container with a fresh install? (y/n)' } else { $InstallYesNo = Read-Host '--> Do you want to replace the stopped container with a fresh install? (y/n)' } } while($InstallYesNo -notin "y", "n") if ($InstallYesNo -eq "n") { Write-Host 'Install cancelled.' Write-Header Write-Status Write-Menu exit } else { $Script:totalSteps = $Script:totalSteps + 5 $Script:installType = "u" } } else { $Script:installType = "f" } } function New-Realm { #Create realm file Write-Host "" $Script:stepCount = $Script:stepCount + 1 Write-Host "Step $Script:stepCount of $Script:totalSteps -->" -ForegroundColor DarkGray Write-Host "Import realm file..." if($Script:realmExportPath -ne "") { docker exec keycloak "c:/keycloak/keycloak-$($Script:tag)/bin/kcadm.bat" create realms -f NexusRealm-import.json } else { docker exec keycloak "c:/keycloak/keycloak-$($Script:tag)/bin/kcadm.bat" create realms -f NexusRealm-default.json } } function Restart-Container { # Check that container is running if($containerStatus -eq 0){ Write-Output "Restarting the container $containerName..."; docker container restart $containerId; Write-Output "The container $containerName has restarted with ID: $containerId"; Start-Sleep -s 10 Get-Status } elseif($containerStatus -eq 1) { Write-Output "The container $containerName is currently stopped with ID: $containerId."; Write-Output "Starting container $containerName..."; docker start $containerName Start-Sleep -s 15 Get-Status } else { Write-Output "The container $containerName doesn't exist. Here are the current running containers:"; docker container ls; } } function Set-Admin{ Write-Host "" $Script:stepCount = $Script:stepCount + 1 Write-Host "Step $Script:stepCount of $Script:totalSteps -->" -ForegroundColor DarkGray Write-Host "Creating admin user..." docker exec -d keycloak "c:/keycloak/keycloak-$($Script:tag)/bin/add-user-keycloak.bat" -u $Script:adminUser -p $Script:adminPassword Start-Sleep -Seconds 15 Write-Host "Admin user added." if($Script:realmExportPath -eq ""){ Write-Host "" $Script:stepCount = $Script:stepCount + 1 Write-Host "Step $Script:stepCount of $Script:totalSteps -->" -ForegroundColor DarkGray Restart-Container } } function Start-Container { # Check that container is running if($containerStatus -eq 0){ Write-Output "The container $containerName is already running with ID: $containerId"; } elseif($containerStatus -eq 1) { Write-Output "Starting container $containerName..."; docker start $containerName Start-Sleep -s 15 Get-Status Write-Output "The container $containerName has started with ID: $containerId"; } else { Write-Output "The container $containerName doesn't exist. Here are the current running containers:"; docker container ls; } } # # Script for Keycloak Container Management # # Initialize State Variables $Script:dockerEngine = docker version $Script:dockerEngine = $? $Script:containerName = 'keycloak' $Script:containerId = '' $Script:containerStatus = -1 $Script:containerStatusString = '' $Script:imageName = "" $Script:stepCount = 0 $Script:totalSteps = 0 $Script:installType = '' $Script:tag = '' $Script:realmExportPath = '' $Script:adminUser = '' $Script:adminPassword = '' $Script:realmYesNo = '' function Start-KeycloakContainerConsole { Get-Status Write-Header Write-Status Write-Menu exit } function Stop-Container { # Check that container is running if($containerStatus -eq 0){ Write-Output "Stopping the container $containerName..."; docker container stop $containerId; Start-Sleep -s 10 Get-Status Write-Output "The container $containerName has stopped with ID: $containerId"; } elseif($containerStatus -eq 1) { Write-Output "The container $containerName is already stopped with ID: $containerId."; } else { Write-Output "The container $containerName doesn't exist. Here are the current running containers:"; docker container ls; } } function Submit-CLILogin{ #Use Keycloak CLI to import realm file Write-Host "" $Script:stepCount = $Script:stepCount + 1 Write-Host "Step $Script:stepCount of $Script:totalSteps -->" -ForegroundColor DarkGray Write-Host "Starting Keycloak CLI..." if(-not $adminUser){ #Prompt User - Ask for an Admin user name do{ $Script:adminUser = Read-Host '--> Login with Admin user name.' } while($Script:adminUser -in "") #Prompt Password - Ask for an Admin password do{ $Script:adminPassword = Read-Host '--> Login with Admin password.' } while($Script:adminPassword -in "") } docker exec keycloak "c:/keycloak/keycloak-$($Script:tag)/bin/kcadm.bat" config credentials --server http://localhost:8080/auth --realm master --user $Script:adminUser --password $Script:adminPassword #Write-Host "Give 10 seconds to login to CLI..." Start-Sleep -s 10 } function Uninstall-Container { Clear-Host Write-Host "****************************************************************************************************" Write-Host "** **" Write-Host "** Uninstall Keycloak **" Write-Host "** **" Write-Host "****************************************************************************************************" $Script:stepCount = 0 $Script:totalSteps = 2 Write-Host "" #Prompt - Ask if they want to export their current Realm and Users file do{ $Script:realmYesNo = Read-Host '--> Before uninstalling, do you want to export your current Realm and User Settings to a file? (y/n)' } while($Script:realmYesNo -notin "y", "n") #Export Realm and Users file if($Script:realmYesNo -eq "y") { Get-ExportPath Get-Realm Export-Realm } elseif($Script:containerStatus -eq 0) { $Script:stepCount = $Script:stepCount + 1 $Script:totalSteps = $Script:totalSteps + 1 Write-Host "Step $Script:stepCount of $Script:totalSteps -->" -ForegroundColor DarkGray Stop-Container } # Remove container $Script:stepCount = $Script:stepCount + 1 Write-Host "Step $Script:stepCount of $Script:totalSteps -->" -ForegroundColor DarkGray Write-Output "Removing the container $Script:containerName ..." docker rm $Script:containerName; Write-Output "The container $Script:containerName has been removed."; Write-Host "" # Remove image $Script:stepCount = $Script:stepCount + 1 Write-Host "Step $Script:stepCount of $Script:totalSteps -->" -ForegroundColor DarkGray Write-Output "Removing the docker image $Script:imageName ..." docker rmi $Script:imageName Write-Output "The docker image $Script:imageName has been removed."; Write-Host "" Write-Host "" Read-Host "--> Uninstall complete. Hit enter to continue..." } function Update-Realm { #Create realm file Write-Host "" $Script:stepCount = $Script:stepCount + 1 Write-Host "Step $Script:stepCount of $Script:totalSteps -->" -ForegroundColor DarkGray Write-Host "Import realm file..." if($Script:realmExportPath -ne "") { docker exec keycloak "c:/keycloak/keycloak-$($Script:tag)/bin/kcadm.bat" update realms/NexusPortal -f NexusRealm-import.json } else { docker exec keycloak "c:/keycloak/keycloak-$($Script:tag)/bin/kcadm.bat" update realms/NexusPortal -f NexusRealm-default.json } } # Display Console Header function Write-Header { Clear-Host Write-Host "****************************************************************************************************" Write-Host "** **" Write-Host "** Keycloak Container Console **" Write-Host "** **" Write-Host "****************************************************************************************************" if(-Not $Script:dockerEngine){ Write-Host "** **" Write-Host "** Docker is not running or not installed. **" Write-Host "** Start docker or go to www.docker.com to download the installer. **" Write-Host "** **" Write-Host "****************************************************************************************************" Read-Host "--> Hit enter to continue..." exit } } function Write-Menu { Write-Host "** **" Write-Host "** s --- Start the Keycloak Container **" Write-Host "** t --- Stop the Keycloak Container **" Write-Host "** r --- Restart the Keycloak Container **" Write-Host "** **" Write-Host "** d --- Define an Admin user and password **" Write-Host "** m --- Import a realm and user file into Keycloak **" Write-Host "** x --- Export a realm and user file from Keycloak **" Write-Host "** **" Write-Host "** i --- Install a new Keycloak Container **" Write-Host "** **" Write-Host "** q --- Quit **" Write-Host "** **" Write-Host "****************************************************************************************************" #Reset Steps $Script:stepCount = 0 $Script:totalSteps = 0 $Script:realmExportPath = "" #Prompt User - Pick an option do{ do{ $Option = Read-Host '--> Choose one of the above options' } while($Option -notin "s", "t", "r", "m", "x", "i", "q") if ($Option -eq "q"){ Clear-Host exit } else{ if ($Option -eq "s") { Start-Container } elseif ($Option -eq "t") { Stop-Container } elseif ($Option -eq "r") { Restart-Container } elseif ($Option -eq "m") { $Script:totalSteps = $Script:totalSteps + 1 Get-ImportFile Import-Realm Submit-CLILogin Update-Realm Write-Host "" Write-Host "Realm file imported from: $Script:realmExportPath" Read-Host "--> Hit enter to continue..." } elseif ($Option -eq "x") { $Script:totalSteps = $Script:totalSteps + 1 Get-ExportPath Get-Realm Export-Realm $Script:stepCount = $Script:stepCount + 1 Write-Host "Step $Script:stepCount of $Script:totalSteps -->" -ForegroundColor DarkGray Start-Container Write-Host "" Write-Host "Realm file exported to: $Script:realmExportPath" Read-Host "--> Hit enter to continue..." } elseif ($Option -eq "i") { Install-Type #If this is an uninstall if ($Script:installType -eq "u") { Uninstall-Container } Install-Container } Write-Header Write-Status Write-Menu } } while($Option -ne "q") } function Write-Status { Write-Host "** **" Write-Host "** Container Status: " -NoNewLine if ($Script:containerStatus -eq 0){ Write-Host "$Script:containerStatusString" -ForegroundColor DarkGreen -NoNewline } elseif ($Script:containerStatus -eq 1){ Write-Host "$Script:containerStatusString" -ForegroundColor Yellow -NoNewline } elseif ($Script:containerStatus -eq 2){ Write-Host "$Script:containerStatusString" -ForegroundColor Red -NoNewline } Write-Host " **" -ForegroundColor White Write-Host "** **" } |