Universal Dashboard 2.7 and UDStudio

There’s nothing too fancy about the login page. I do have a custom theme set, but this is the basics:

$LoginPage = New-UDLoginPage -Title "Technology Portal Login" -AuthenticationMethod $AuthenticationMethod -WelcomeText "CCCTC Technology Portal" -PageBackgroundColor $RedBackgroundColor -LoginFormBackgroundColor $RedBackgroundColor -LoginFormFontColor "#FFFFFF" -Logo $CTCLogo -LoadingText "Please wait while loading..."

I’m wondering if this is an error coming from UD. Can you enable UD logging?

Enable-UDLogging 

See if the error An item with the same key has already been added. is in the log.

I enabled logging, and it doesn’t show in the logs. It seems to be coming from the VSCode extension.

Alright. Sounds good. The hunt continues!

@nittanygeek How are you doing your authentication method? Noticed the same behavior with my dashboard. Unsure if related, but just curious.

Hey @jorf, are you using -AutoReload on Start-UDDashboard?

I’ve been trying to reproduce this and it doesn’t seem like any ol’ login page is causing the issue in my environment.

For example, I this guy works fine.

$AuthenticationMethod = New-UDAuthenticationMethod -Endpoint {
    param([PSCredential]$Credential)

    New-UDAuthenticationResult -Success -UserName "Adam"

    $Test
}

$AuthenticationPolicy = New-UDAuthorizationPolicy -Name 'Policy' -Endpoint {
    $true 
}

$LoginPage = New-UDLoginPage -AuthenticationMethod $AuthenticationMethod -AuthorizationPolicy $AuthenticationPolicy

@jorf, local AD. Slightly redacted code:

# Authentication
$AuthenticationMethod = New-UDAuthenticationMethod -Endpoint {
    param([PSCredential]$Credentials)
    $UserDomain = "foo.local"
    $ContextType = [System.DirectoryServices.AccountManagement.ContextType]::Domain

    Try {
        $PrincipalContext = New-Object System.DirectoryServices.AccountManagement.PrincipalContext $ContextType,$UserDomain
    } Catch {
        New-UDAuthenticationResult -ErrorMessage "Server could not be reached!"
    }
    
    $ValidAccount = $PrincipalContext.ValidateCredentials($Credentials.UserName,$Credentials.GetNetworkCredential().Password)
    If (-not($ValidAccount)) {
        New-UDAuthenticationResult -ErrorMessage "Invalid login credentials!"
    } else {
        $adminMembers = Get-ADGroupMember "InsertYourDashboardSecurityGroupName" | Select-Object -ExpandProperty SamAccountName
        if ($adminMembers -contains $Credentials.UserName) {
            New-UDAuthenticationResult -Success -UserName $Credentials.UserName
            $Cache:UserName = $Credentials.UserName
            $Cache:UserDepartment = (Get-ADUser -Identity $Credentials.UserName -Properties Department).Department
        } else {
            New-UDAuthenticationResult -ErrorMessage "You do not have permission to access this site!"
        }
    }
}

@adam Yeah, I had -AutoReload on initially. Just tried taking it off to no avail. I am also using local AD authentication, similar to @nittanygeek.

$AuthenticationMethod = New-UDAuthenticationMethod -Endpoint {
  param([PSCredential]$Credentials)
  Function Test-Credential 
  {
    [OutputType([Bool])]
        
    Param (
      [Parameter(
          Mandatory = $true,
          ValueFromPipeLine = $true,
          ValueFromPipelineByPropertyName = $true
      )]
      [Alias(
          'PSCredential'
      )]
      [ValidateNotNull()]
      [System.Management.Automation.PSCredential]
      [System.Management.Automation.Credential()]
      $Credential,
    
      [Parameter()]
      [String]
      $Domain = $Credential.GetNetworkCredential().Domain
    )
    
    Begin {
      $null = [System.Reflection.Assembly]::LoadWithPartialName('System.DirectoryServices.AccountManagement')
    
      $principalContext = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext -ArgumentList (
        [System.DirectoryServices.AccountManagement.ContextType]::Domain, $Domain
      )
    }
    
    Process {
      foreach ($item in $Credential) 
      {
        $networkCredential = $Credential.GetNetworkCredential()
                
        Write-Output -InputObject $(
          $principalContext.ValidateCredentials(
            $networkCredential.UserName, $networkCredential.Password
          )
        )
      }
    }
    End {
      $principalContext.Dispose()
    }
  }
  $adusergroup = 'Users'
  $adadmingroup = 'Admins'
  if ((Test-Credential -Credential $Credentials)) 
  {
    if(Get-ADGroupMember -Identity $adadmingroup | Where-Object -FilterScript {
        $_.SamAccountName -eq $Credentials.UserName
    })
    {
      New-UDAuthenticationResult -Success -UserName $Credentials.UserName -Role 'Administrator' -OutVariable AuthenticationResult
    }
    elseif(Get-ADGroupMember -Identity $adusergroup | Where-Object -FilterScript {
        $_.SamAccountName -eq $Credentials.UserName
    })
    {
      New-UDAuthenticationResult -Success -UserName $Credentials.UserName -Role 'User' -OutVariable AuthenticationResult
    }
    else 
    {
      New-UDAuthenticationResult -ErrorMessage "Only members of $adusergroup have access."
    }
  }
  New-UDAuthenticationResult -ErrorMessage 'Invalid Credentials, please try again.'
}

Thanks. That script broke in my lab. I’ve published version 0.1.2 that should resolve this. Please try upgrading and let me know. might take a minute before it’s available on the VS Marketplace.

Sorry for the delay. It appears to still be throwing the same two errors in my environment.

Dang. Thought I nailed it.

Can you please run the following:

$PSVersionTable
Get-Module UniversalDashboard -ListAvailable
Get-UDDashboard
Get-UDStudioDashboard

Here you go:

Name                           Value
----                           -----
PSVersion                      5.1.18362.145
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.18362.145
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

Name              : UniversalDashboard
Path              : C:\Users\jorf\Documents\WindowsPowerShell\Modules\UniversalDashboard\2.7.0\UniversalDashboard.psd1
Description       : Cross-platform module for developing websites and REST APIs.
Guid              : c7894dd1-357e-4474-b8e1-b416afd70c2d
Version           : 2.7.0
ModuleBase        : C:\Users\jorf\Documents\WindowsPowerShell\Modules\UniversalDashboard\2.7.0
ModuleType        : Script
PrivateData       : {PSData}
AccessMode        : ReadWrite
ExportedAliases   : {}
ExportedCmdlets   : {[New-UDNivoChart, New-UDNivoChart], [New-UDNivoChartAxisOptions, New-UDNivoChartAxisOptions], [New-UDNivoPattern, New-UDNivoPattern], [New-UDNivoFill, New-UDNivoFill]...}
ExportedFunctions : {[Out-UDChartData, Out-UDChartData], [Out-UDGridData, Out-UDGridData], [Out-UDTableData, Out-UDTableData], [New-UDChartDataset, New-UDChartDataset]...}
ExportedVariables : {}
NestedModules     : {}


AdminMode        : 
Name             : Dashboard0
Port             : 10001
Running          : True
DashboardService : UniversalDashboard.Services.DashboardService


AdminMode        :
Name             : Dashboard0
Port             : 10001
Running          : True
DashboardService : UniversalDashboard.Services.DashboardService

Thanks! It’s strange. I was expecting that last command to fail. There is something I am missing…

> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.1.17763.316
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.17763.316
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1


> Get-Module UniversalDashboard -ListAvailable


    Directory: C:\Program Files\WindowsPowerShell\Modules


ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Script     2.7.0      UniversalDashboard                  {New-UDNivoChart, New-UDNivoChartAxisOptions, New-UDNivoPattern, New-UDNivoFill...}
Script     2.6.2      UniversalDashboard                  {New-UDNivoChart, New-UDNivoChartAxisOptions, New-UDNivoPattern, New-UDNivoFill...}

And:

> Get-UDDashboard


AdminMode        :
Name             : Dashboard0
Port             : 10001
Running          : True
DashboardService : UniversalDashboard.Services.DashboardService



> Get-UDStudioDashboard


AdminMode        :
Name             : Dashboard0
Port             : 10001
Running          : True
DashboardService : UniversalDashboard.Services.DashboardService

Another try. I actually was able to reproduce it this time with your help! The issue was that ConvertTo-Json, which the extension uses, was throwing an exception in certain circumstances when running Windows PowerShell 5.1. Please upgrade to 0.1.3 and see if it works for you.

1 Like

That did the trick for me. Thanks @adam! Excited to use the studio in the future.

1 Like

I upgraded my test lab without issue, but when I did my production site, I only ever got not authorized page. I ended up having to rollback to 2.5.2 to restore site for now. Has anyone else seen this on the upgrade?

Running on IIS site with Windows Auth setup for login. Utilizing new-udauthorization policy for each AD group that is granted permissions across various pages. Example of one of them below, redacted real data out.

$AdminPolicy = New-UDAuthorizationPolicy -Name "WFA-Admin" -Endpoint {
param($ClaimsPrincipal)
$ClaimsPrincipal.HasClaim("http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid", "S-1-0-00-000000000-0000000000000-00000000-0000") 

}

I remove all sites in my IIS page folder except for my dashboard and page files and then recopied from the module folder right over. Only thing i left was web.config since i have it set for redirects and such.

You can’t use $ClaimsPrincipal in 2.7.0, Its bugged.

Swap to $User and you will be fine.

I was hitting my head wondering why I was getting enum errors on some session variables and I had come up with an idea to make a thread safe setup but then this morning I see this update makes session variables thread safe and now everything works. I appreciate the bug fix.

1 Like