I have a dashboard that I previously posted about which I have now completed work on. It runs fine if I start it up via a PowerShell terminal, but if I use Publish-UDDashboard to get it running as a service I’m just getting an error stating ’ The system cannot find the path specified.’.
My main guess with this is down to the fact that I’m importing my Azure credentials via an Import-Clixml command and the service will not be running as the same account that created the credential file.
Does this sound as if it’s the likely cause? If so, is there a ‘best practice’ way of securely storing the credentials and also using them in a dashboard?
1 Like
@stuartluscombe Using CliXml is fine for storing creds on a windows box, but yes you are limited to using the same user account on that machine. One solution would be to run the service with a service account, and to save the file using that service account as well. I used to do the same thing with scheduled tasks and it works pretty well.
That said I don’t think that Publish-UDDashboard
offers anything in the way specifying a service account so you’d have to do that manually after creating the service.
You might be able to look into using the Windows credential store as well, but I think you’d have the same user/machine limitation.
I’m running dashboards in IIS, and I struggled to find the right way to do this but ended up using encrypted configuration sections in the web config file. I wasn’t aware these existed but it’s a pretty nice solution that web devs have probably been using for years to store database connection strings. I just store a password combination in the config instead of a connection string.
2 Likes
@mattmcnabb Thanks for your response. I’ll take a look into using a service account and failing that, the IIS config method you mentioned.
@mattmcnabb I’m in the process of setting the dashboard up in IIS and have encrypted the username/password within web.config, but I have no idea how to read the values back out. I’m currently searching for an answer, but thought I’d ask here in case you can provide a pointer at the solution.
@stuartluscombe I think there are a couple of ways to do that. Mine was encrypted using the aspnet_regiis tool, and I think you could do the same to decrypt as well. However, I am using something like this to read out the credential into a PSCredential
object:
function Get-WebConfigCredential
{
[CmdletBinding()]
param
(
[string]
$UserName,
[string]
$Path
)
$Path = Convert-Path $Path
# I have no idea what any of this does - it was given to me and I think it came from a blog somewhere :)
$null = [appdomain]::CurrentDomain.SetData("APP_CONFIG_FILE", $Path)
$null = [appdomain]::CurrentDomain.GetData("APP_CONFIG_FILE")
$null = [Configuration.ConfigurationManager].GetField("s_initState", "NonPublic, Static").SetValue($null, 0)
$null = [Configuration.ConfigurationManager].GetField("s_configSystem", "NonPublic, Static").SetValue($null, $null)
$t = ([Configuration.ConfigurationManager].Assembly.GetTypes() | where {$_.FullName -eq "System.Configuration.ClientConfigPaths"})[0]
$t.GetField("s_current", "NonPublic, Static").SetValue($null, $null)
# output the value from the encrypted connection string section as a credential
$Splat_SecureString = @{
String = [System.Configuration.ConfigurationManager]::ConnectionStrings[$UserName].ConnectionString
AsPlainText = $true
Force = $true
}
$SecurePassword = ConvertTo-SecureString @Splat_SecureString
[pscredential]::new($UserName, $SecurePassword)
}
This way assumes that you’re storing the credentials in the web.config the same way that I am, which is a hack and looks like this:
<connectionStrings>
<add name="Sterling" connectionString="DangerZone!" />
</connectionStrings>
Essentially the “name” is the username and the connectionString is the password. So if you have multiple credentials in the web.config this will allow you to specify which one to return.
Note that this also assumes you’re using the DPAPI provider to encrypt the web.config and not RSA.