-
Notifications
You must be signed in to change notification settings - Fork 112
new command to request just in time jit database access for a unified development environment ude #897 #898
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
…e exports Co-authored-by: FH-Inway <[email protected]>
…seJITAccess Co-authored-by: FH-Inway <[email protected]>
…tring or a PSCredential object
This pull request was automatically created by the d365fo.tools-Generate-Text action'
|
There is a better way to pass the password to SSMS--Credential Manager. |
|
Thank you @akasparas , I will look into that. Appreciate the hint! |
|
Aparently, Import of CredentialManager module is little different depending on Powershell version. Please take a look at Troy's comment https://learn.microsoft.com/en-us/answers/questions/459844/get-storedcredential-not-recognized-even-though-it?source=docs before someone complains that code is not working. |
|
Awesome work! |
Below works - I just confirmed with locally on my machine, with static values from a Tier2. New-StoredCredential -UserName $username -Password $password -Target "Microsoft:SSMS:${ssmsVersion}:${serverName}:${username}:${sqlServerGUID}:1" > $nullThe New-StoredCredential -UserName $username -Password $password -Target "Microsoft:SSMS:$($ssmsVersion):$($serverName):$($username):$($sqlServerGUID):1" > $nullAll my testing was done in PowerShell 5.1, with a set of Install-Module CredentialManager & Import-Module CredentialManager. The Install-Module was done, and then I started a fresh PowerShell session - from there the auto-import functionality worked as expected. |
|
Here is a hack to find all SSMS installed on the machine: # Oneliner
Get-ChildItem -Path Registry::HKEY_CLASSES_ROOT\ssms.c2s*\shell\Open\Command | Select-Object -ExpandProperty PsPath | ForEach-Object {(Get-ItemProperty -Path $_)."(Default)"} | Select-String -Pattern '^[\"]?(.*ssms\.exe)["]?\s*"%1"' | ForEach-Object { $_.Matches.Groups[1].Value }
#Indented
Get-ChildItem `
-Path Registry::HKEY_CLASSES_ROOT\ssms.c2s*\shell\Open\Command | `
Select-Object -ExpandProperty PsPath | `
ForEach-Object {(Get-ItemProperty -Path $_)."(Default)"} | `
Select-String -Pattern '^[\"]?(.*ssms\.exe)["]?\s*"%1"' | `
ForEach-Object { $_.Matches.Groups[1].Value }
#Formatted
Get-ChildItem `
-Path Registry::HKEY_CLASSES_ROOT\ssms.c2s*\shell\Open\Command | `
Select-Object -ExpandProperty PsPath | `
ForEach-Object { (Get-ItemProperty -Path $_)."(Default)" } | `
Select-String -Pattern '^[\"]?(.*ssms\.exe)["]?\s*"%1"' | `
ForEach-Object { $_.Matches.Groups[1].Value } |
|
Just tested with 20 and 21 of SSMS - without issues. Just ran the |
|
If you have to search for registered SSMS paths anyway, maybe it makes sense to have parameter -ssms. Without arguments--latest, with argument--particular version? SSMS.exe usually have long path, so it would be less typing for admin. |
I'm not entirely sure I fully understand. Please share more details how you would envision using cmdlets like this. |
|
Thanks for the research, the hack to find the installed SSMS should be useful.
If I understand correctly, the ask is to instead of the Regarding the stored credential: @Splaxi do we want to take a dependency on the CredentialManager module? My vote would be no, at least in regards to a dependency at installation time. The overhead and risk that comes with it does not justify the relatively minor gain in quality of life for this rather rare use case. I would be more open to a run time dependency, i.e. have the command check if the module is available. If not, it falls back to the current behavior and tells the user to install the module. If yes, it would create the credential. I would also recommend that instead of CredentialManager (updated last in 2016 and source code archived in 2021) we test TUN.CredentialManager instead. It seems to be the successor to CredentialManager and compatible with PowerShell Core. Another option could be to write our own internal functions for creating a stored credential, since we only need a small part of the full CredentialManager functionality. Yet another option could be to write a How-To in the wiki that explains how to use |
|
I would like the following be possible: Get an JIT, persist it on my local machine and have SSMS open - in 1 operation / flow. Be that by pipes or other fancy tricks. I would like to list the current Stored Credentials, with server + database + username. On top of that - I would like to clear them out, when they have rendered obsolete, in the background. I'm willing to put in any effort to make that happen, as I feel we are very close to make it happen. I'll dive into the TUN.CredentialManager and see where it takes me. |
|
With the TUN module, we have some neat stuff available:
With that - We can build some cmdlets, and features - what will make the life with UDE easier... If we use the Comment for that database name, e.g. "db:db_d365opsprod_ax_97ce;" - then we should have all the capabilities directly from the Credential Manager store. LastWritten will be use to validate that a given username / password combination has expired (9+ hours), and when our module loads, we can start a background tasks, that will remove expired. We can expose a setting, in the |
Yes, good idea 👍 |
|
Set-D365UdeDatabaseCredential They are ready for some initial testing... |
Have not been able to find them, let me know once you push them to a public repo, then I will take a look.
I looked into the hack. It does not work on older SSMS versions, since the registry path is different there. The question is how many versions backwards we want to support. We will also have to check with each new SSMS versions if the registry paths still work and update them if not. Also not sure if we need the $registryPathDMX = "Registry::HKEY_CLASSES_ROOT\ssms.dmx*\shell\Open\Command" # SSMS 18
$registryPathC2S = "Registry::HKEY_CLASSES_ROOT\ssms.c2s*\shell\Open\Command" # SSMS 20 + 21
$registryEntry = Get-ItemProperty -Path $registryPathDMX
if (-not $registryEntry) {
$registryEntry = Get-ItemProperty -Path $registryPathC2S
}
if (-not $registryEntry) {
throw "SSMS installation not found in registry."
}
$ssmsCommand = $registryEntry."(Default)"
$ssmsPathMatches = $ssmsCommand | Select-String -Pattern '^[\"]?(.*ssms\.exe)["]?\s*"%1"'
$ssmsPath = $ssmsPathMatches.Matches.Groups[1].ValueBased on that, I had GitHub Copilot (GPT-5) vibe code an internal function to determine the ssms.exe path: https://github.com/FH-Inway/d365fo.tools/blob/695897325bec8cd280630358cfae034f8b977e0d/d365fo.tools/internal/functions/get-ssmspath.ps1 |
Maybe this could make it simpler, and support multiple versions over time Get-ChildItem `
-Path Registry::HKEY_CLASSES_ROOT\ssms.*\shell\Open\Command | `
Select-Object -ExpandProperty PsPath | `
ForEach-Object { (Get-ItemProperty -Path $_)."(Default)" } | `
Select-String -Pattern '^[\"]?(.*ssms\.exe)["]?\s*"%1"' | `
ForEach-Object { $_.Matches.Groups[1].Value } | Select-Object -Unique |

This pull request adds the new PowerShell cmdlet
Request-D365DatabaseJITAccessfor requesting just-in-time (JIT) database access for D365 Finance and Operations unified development environments (UDE). The cmdlet allows users to obtain temporary credentials for direct database access, supporting multiple authentication methods and integration with SQL Server Management Studio. The changes also register the new cmdlet in the module manifest.Resolves #897
New experience
Open SSMS
This is the simplest way to use the new command, but not necessarily the best. One quality of life parameter is
-SQLServerManagementStudioPath, which lets you specify the path to the SQL Server Management Studio ssms.exe (usually the path looks similar toC:\Program Files (x86)\Microsoft SQL Server Management Studio 18\Common7\IDE\ssms.exe). This lets the command open SSMS with the connection information. Unfortunately, the password cannot be provided in newer SSMS versions. So instead, it is copied to the clipboard so the user can paste it in the connection form.Unfortunately, getting to the connection form without the password is a bit tricky. First, you get a warning dialog asking if it should connect.



Since the password is missing at that point, this fails with an error dialog.
After that, you get to the connection form where the password can be pasted and the connection be established.
May take a few tries until the firewall accepts the IP address (the command will automatically determine the IP address, but can also be provided with the
-ClientIPAddressparameter).Export bacpac
The access information can also be used to export the database .bacpac file like so: