Unable to manage admin

In our instance, authentication to PowerShell Universal is done through Azure accounts. The PU instance is automatically redeployed regularly without the persistence of a database. Because it is not possible to disable forms authentication, i want to reject the local admin authentication or set the password on initialization. To reject the authentication i tried this in the authentication.ps1, but that did not work.

Set-PSUAuthenticationMethod -Type "OpenIDConnect" -CallbackPath "/auth/signin-oidc" -ClientId $Env:Authentication__OIDC__ClientId -ClientSecret $Env:Authentication__OIDC__ClientSecret -Resource $Env:Authentication__OIDC__Resource -Authority $Env:Authentication__OIDC__Authority -SaveTokens $true -UseTokenLifetime $true 
Set-PSUAuthenticationMethod -Type "Form" -scriptblock {
	param($Credential)

	<# does not work either
	$Result = [Security.AuthenticationResult]::new()
	$Result.UserName = $credential.Username
	$Result.Success = $False
	return $Result
	#>

	New-PSUAuthenticationResult -ErrorMessage 'No'
	if ($Credential.UserName -eq 'Admin') {
		New-PSUAuthenticationResult -ErrorMessage 'Not Admin'
	}
	else {
		New-PSUAuthenticationResult -ErrorMessage 'Not Admin'
	}
}

Is there a way to set the admin password on initialization? Or can we disable the forms authentication entirely? Even if we do not have access anymore to PU, we still have access to the files and could, if we want to, enforce yourself into PU.

Product: PowerShell Universal
Version: 3.8.9

If you create a Startup trigger script to delete the admin account, it will remove the ability for them to login. We do recreate the admin account if it is missing on startup but the startup trigger runs after that so you could just always remove it.

With this script

# It all starts with a single line of powershell code.
$LocalAdmin = Get-PSUIdentity -Name admin
if ($LocalAdmin) {
    write-verbose "Found local admin $($LocalAdmin.name), removing it now" -Verbose
    #Remove-PSUIdentity -Identity $LocalAdmin
    #Remove-PSUIdentity -id $LocalAdmin.id
    Remove-PSUIdentity -Identity $LocalAdmin -Integrated
}
else {
    Write-Vebrose "Local admin already deleted" -Verbose
}

I get

[verbose] Found local admin admin, removing it now 
[error] Status(StatusCode="Unknown", Detail="Exception was thrown by handler.", DebugException="Grpc.Core.Internal.CoreErrorDetailException: {"created":"@1681717660.714133961","description":"Error received from peer ipv4:127.0.0.1:40949","file":"/var/local/git/grpc/src/core/lib/surface/call.cc","file_line":953,"grpc_message":"Exception was thrown by handler.","grpc_status":2}") 

Besides not being able to delete the admin, I can only test this in my docker environment due to this error locally

[error] Call failed. No connection could be made because the target machine actively refused it. (localhost:80) GET http://localhost/api/v1/accessible 

When using the VS Code extension i also get this error

image

When the extension is connected to my docker instance, the configuration screen within the extension has got data, but when using it locally it is empty. The dashboards are manageable though.

I think this is because PU tries to access the API on port 80, but it is not there. Locally i am running the dashboard on http 5000 and https 443 (the last one is needed due to the Azure authentication). The docker instance is just default configuration because the appservice manages https.

And another bug seems to be that if the scripts.ps1 in the .universal is placed there manually, but not created through PU, the contents are not displayed within the admin page. Though the scripts are available and will be launched through the triggers for instance.

I see the issue with Remove-PSUIdentity. It looks like we’ll need to patch that. I’ll make sure we get it in 3.8.10 to see if that helps resolve your issue.

As for the scripts.ps1, it’s surprising you can run scripts from triggers that don’t show in the UI.

If you navigate to this URL, does it display all your scripts?

http://localhost:5000/api/v1/scripts

I get “Page Not Found”, this also happens for https://localhost/api/v1/scripts

Sorry. Should be singular.

https://localhost/api/v1/script

Can you try switching to list view of expanding the repository folder on the left?


And this how it looks on disk

In regards to removing the admin account, with 3.8.10 I still get an error:

[verbose] Found local admin admin, removing it now 
[error] Status(StatusCode="Unknown", Detail="Exception was thrown by handler.", DebugException="Grpc.Core.Internal.CoreErrorDetailException: {"created":"@1681901063.139000000","description":"Error received from peer ipv6:[::1]:61529","file":"..\..\..\src\core\lib\surface\call.cc","file_line":953,"grpc_message":"Exception was thrown by handler.","grpc_status":2}") 

i have tested your script in my env and i can confirmed it works with 3.8.10 release, am hosting in IIS

I ran through this scenario using docker on Windows with 3.8.10. This is my configuration.

docker pull ironmansoftware/universal
docker run --name 'PSU' -p 5000:5000 -v C:\src\docker-repo:/root/.PowerShellUniversal/Repository ironmansoftware/universal 

image

scripts.ps1

New-PSUScript -Name 'Script.ps1' -Path 'Script.ps1'
New-PSUScript -Name 'admin.ps1' -Path 'admin.ps1'

triggers.ps1

New-PSUTrigger -Name 'remove admin' -TriggerScript 'admin.ps1' -EventType 'ServerStarted'

admin.ps1

Get-PSUIdentity -Name 'admin' -Integrated | Remove-PSUIdentity -Integrated
New-PSUIdentity -Name 'admin2' -CredentialVault "Database" -Password (ConvertTo-SecureString -String 'admin' -AsPlainText -Force) -Integrated

Both of my scripts show up in the UI and the trigger is properly called.

The admin user was removed and the admin2 user was added and I can login with that account.

If i run the script locally or in my docker instance, the result is always the same. Locally i have started with a clean slate. No preconfigured scripts.ps1 and triggers.ps1. Clean database. After launching PU, creating a script and running it directly, same error. It does not matter if the default environment is used, or powershell 7 which we have available.

Docker:

[error] Status(StatusCode="Unknown", Detail="Exception was thrown by handler.", DebugException="Grpc.Core.Internal.CoreErrorDetailException: {"created":"@1682338411.448086893","description":"Error received from peer ipv4:127.0.0.1:37189","file":"/var/local/git/grpc/src/core/lib/surface/call.cc","file_line":953,"grpc_message":"Exception was thrown by handler.","grpc_status":2}") 

Locally:

Remove-PSUIdentity: [pah]\dashboard\data\UniversalAutomation\Repository\scripts\manage_admin.ps1:6:19
Line |
   6 |      $LocalAdmin | Remove-PSUIdentity -Integrated
     |                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | Status(StatusCode="Unknown", Detail="Exception was thrown by handler.", DebugException="Grpc.Core.Internal.CoreErrorDetailException: {"created":"@1682338588.341000000","description":"Error received from peer ipv6:[::1]:50661","file":"..\..\..\src\core\lib\surface\call.cc","file_line":953,"grpc_message":"Exception was thrown by handler.","grpc_status":2}")

If you set the environment to integrated, do you get a different error message? It will not be using gRPC in this case.

Also, are you using the stock docker image from docker hub for this container? What is your host OS?

Setting it to integrated solves the issue.We are running PU locally on windows and in docker in Linux. We only had the option between the default and 7 because our environment.ps1 looks likes this

if ($PSVersionTable.OS -like '*Linux*') {
    New-PSUEnvironment -Name "7" -Path "/usr/bin/pwsh" -Variables @('*')
} Else {
    New-PSUEnvironment -Name "7" -Path "C:\Program Files\PowerShell\7\pwsh.exe" -Variables @('*') -EnableDebugger
}

By adding the following line we can use the integrated environment

New-PSUEnvironment -Integrated -Name Integrated

Thanks, that is solved now :slight_smile:

There is still one “problem”, if we declare the scripts.ps1 manually and launch PU, the script does not show up in the interface. I cannot create the same script because PU will not overwrite the existing. The trigger.ps1 works though, it can see and execute the script.

A little update in regards to the script not showing up. If i edit the scripts.ps1 from the .universal folder through the VSCode extension and i save that file, the script will show up.

Another update, I used this in the scripts.ps1 for whatever reason

New-PSUScript -Name "manage_admin.ps1" -Description "Manage PU admin" -Path "$PSSCriptRoot\..\scripts\manage_admin.ps1" -InformationAction "SilentlyContinue" -Environment Integrated

And that does not show up, but when using the following script, upon launch will show up

New-PSUScript -Name "manage_admin.ps1" -Description "Manage PU admin" -Path "scripts\manage_admin.ps1" -Environment "Integrated" -InformationAction "SilentlyContinue"

Problem solved, but i think the interface is having issues with resolving the -Path value.