Skip to content

Instantly share code, notes, and snippets.

@SQLDBAWithABeard
Last active February 17, 2024 01:57
Show Gist options
  • Select an option

  • Save SQLDBAWithABeard/43921494f40dc1461d59445eb44a73ff to your computer and use it in GitHub Desktop.

Select an option

Save SQLDBAWithABeard/43921494f40dc1461d59445eb44a73ff to your computer and use it in GitHub Desktop.
Using Secrets Management
Display the source blob
Display the rendered blob
Raw
{
"metadata": {
"kernelspec": {
"name": ".net-powershell",
"display_name": ".NET (PowerShell)"
},
"language_info": {
"name": "PowerShell",
"version": "7.0",
"mimetype": "text/x-powershell",
"file_extension": ".ps1",
"pygments_lexer": "powershell"
}
},
"nbformat_minor": 2,
"nbformat": 4,
"cells": [
{
"cell_type": "markdown",
"source": [
"# Secrets Management with PowerShell\r\n",
"\r\n",
"You can use the `Microsoft.PowerShell.SecretManagement` module introduced [here](https://devblogs.microsoft.com/powershell/secrets-management-development-release/) to store and retrieve secrets with PowerShell.\r\n",
"\r\n",
"## Installation\r\n",
"\r\n",
"You install it from the PowerShell Gallery using"
],
"metadata": {
"azdata_cell_guid": "8b771475-0092-4e02-97be-5f08e558a584"
}
},
{
"cell_type": "code",
"source": [
"Install-Module Microsoft.PowerShell.SecretManagement -AllowPrerelease"
],
"metadata": {
"azdata_cell_guid": "f2570663-c521-4af5-acdc-075b77901879"
},
"outputs": [],
"execution_count": null
},
{
"cell_type": "markdown",
"source": [
"You need to use the `-PreRelease` flag at the moment as it is in preview. \r\n",
"\r\n",
"## Local Vault\r\n",
"\r\n",
"It will come with a built in local key vault for you to use. You can see this with `Get-SecretVault`"
],
"metadata": {
"azdata_cell_guid": "c13bb6ab-3ee2-41db-a22d-f5b8a0a23443"
}
},
{
"cell_type": "code",
"source": [
"Get-SecretVault"
],
"metadata": {
"azdata_cell_guid": "021b34e8-b115-4042-8f6e-b5790e2ac1e4"
},
"outputs": [
{
"output_type": "display_data",
"data": {
"text/html": "\r\n<div>\r\n <div id='dotnet-interactive-this-cell-47344.572a81723abb42f59f29d82c009aa537' style='display: none'>\r\n The below script needs to be able to find the current output cell; this is an easy method to get it.\r\n </div>\r\n <script type='text/javascript'>\r\n// ensure `require` is available globally\r\nif (typeof require !== typeof Function || typeof require.config !== typeof Function) {\r\n let require_script = document.createElement('script');\r\n require_script.setAttribute('src', 'https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js');\r\n require_script.setAttribute('type', 'text/javascript');\r\n require_script.onload = function () {\r\n loadDotnetInteractiveApi();\r\n };\r\n\r\n document.getElementsByTagName('head')[0].appendChild(require_script);\r\n}\r\nelse {\r\n loadDotnetInteractiveApi();\r\n}\r\n\r\nasync function probeAddresses(probingAddresses) {\r\n function timeout(ms, promise) {\r\n return new Promise(function (resolve, reject) {\r\n setTimeout(function () {\r\n reject(new Error('timeout'))\r\n }, ms)\r\n promise.then(resolve, reject)\r\n })\r\n }\r\n\r\n if (Array.isArray(probingAddresses)) {\r\n for (let i = 0; i < probingAddresses.length; i++) {\r\n\r\n let rootUrl = probingAddresses[i];\r\n\r\n if (!rootUrl.endsWith('/')) {\r\n rootUrl = `${rootUrl}/`;\r\n }\r\n\r\n try {\r\n let response = await timeout(1000, fetch(`${rootUrl}discovery`, {\r\n method: 'POST',\r\n cache: 'no-cache',\r\n mode: 'cors',\r\n timeout: 1000,\r\n headers: {\r\n 'Content-Type': 'text/plain'\r\n },\r\n body: probingAddresses[i]\r\n }));\r\n\r\n if (response.status == 200) {\r\n return rootUrl;\r\n }\r\n }\r\n catch (e) { }\r\n }\r\n }\r\n}\r\n\r\nfunction loadDotnetInteractiveApi() {\r\n probeAddresses([\"http://172.28.176.1:1003/\", \"http://172.29.48.1:1003/\", \"http://192.168.1.69:1003/\", \"http://127.0.0.1:1003/\"])\r\n .then((root) => {\r\n // use probing to find host url and api resources\r\n // load interactive helpers and language services\r\n let dotnet_require = require.config({\r\n context: '47344.572a81723abb42f59f29d82c009aa537',\r\n paths: {\r\n 'dotnet-interactive': `${root}resources`\r\n }\r\n }) || require;\r\n if (!window.dotnet_require) {\r\n window.dotnet_require = dotnet_require;\r\n }\r\n \r\n dotnet_require([\r\n 'dotnet-interactive/dotnet-interactive'\r\n ],\r\n function (dotnet) {\r\n dotnet.init(window);\r\n },\r\n function (error) {\r\n console.log(error);\r\n }\r\n );\r\n })\r\n .catch(error => {console.log(error);});\r\n }\r\n </script>\r\n</div>"
},
"metadata": {}
},
{
"output_type": "stream",
"name": "stdout",
"text": "\r\n"
},
{
"output_type": "stream",
"name": "stdout",
"text": "Name ModuleName ImplementingType\r\n"
},
{
"output_type": "stream",
"name": "stdout",
"text": "---- ---------- ----------------\r\n"
},
{
"output_type": "stream",
"name": "stdout",
"text": "BuiltInLocalVault \r\n"
},
{
"output_type": "stream",
"name": "stdout",
"text": "\r\n"
}
],
"execution_count": 1
},
{
"cell_type": "markdown",
"source": [
"## Adding Secrets\r\n",
"\r\n",
"You can add a secret to the vault with `Set-Secret` It does not give any output"
],
"metadata": {
"azdata_cell_guid": "76441636-a0f4-4d42-a62d-f144876e54c6"
}
},
{
"cell_type": "code",
"source": [
"Set-Secret -Name MyAwesomeSecret -Secret 'BeardsAreAwesome'"
],
"metadata": {
"azdata_cell_guid": "07f92208-f1c9-413f-9d94-31db17a9e440"
},
"outputs": [],
"execution_count": 5
},
{
"cell_type": "markdown",
"source": [
"If you dont want to have your secret in the code (A recommended practice! Otherwise, why would need a key vault) You can prompt for user input with `Read-Host`"
],
"metadata": {
"azdata_cell_guid": "45961345-4c04-49b0-b7fd-40433b88c5cc"
}
},
{
"cell_type": "code",
"source": [
"$Secret = Read-Host \"tell me your secret\" -AsSecureString\r\n",
"Set-Secret -Name ASecretFromMe -SecureStringSecret $Secret"
],
"metadata": {
"azdata_cell_guid": "2c3ecd6e-14f4-43a2-8093-f941e13d7224"
},
"outputs": [],
"execution_count": 8
},
{
"cell_type": "markdown",
"source": [
"or with `Get-Credential`"
],
"metadata": {
"azdata_cell_guid": "969eb143-687e-4e82-ba7b-d14a77bc4e83"
}
},
{
"cell_type": "code",
"source": [
"$Secret = Get-Credential\r\n",
"Set-Secret -Name $Secret.UserName -SecureStringSecret $Secret.Password"
],
"metadata": {
"azdata_cell_guid": "76b9f0c5-9296-4fb6-9393-78b9bba4c817"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": "\r\n"
},
{
"output_type": "stream",
"name": "stdout",
"text": "\u001b[95mPowerShell credential request\u001b[0m\r\n"
},
{
"output_type": "stream",
"name": "stdout",
"text": "Enter your credentials.\r\n"
},
{
"output_type": "stream",
"name": "stdout",
"text": "\r\n"
}
],
"execution_count": 9
},
{
"cell_type": "markdown",
"source": [
"## Retrieving Secrets\r\n",
"\r\n",
"You can retrieve secrets with `Get-Secret`"
],
"metadata": {
"azdata_cell_guid": "b0cd5642-8611-4408-9bdb-d5be5287be22"
}
},
{
"cell_type": "code",
"source": [
"Get-Secret -Name MyAwesomeSecret"
],
"metadata": {
"azdata_cell_guid": "76cee814-f78d-4e7f-b0e9-dd3855baae52"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": "System.Security.SecureString\r\n"
}
],
"execution_count": 6
},
{
"cell_type": "markdown",
"source": [
"This returns a SecureString which you can use in your code.\r\n",
"\r\n",
"You can return the value in plain text with the `-AsPlainText` switch. (Please be careful doing this and understand where this may be logged)"
],
"metadata": {
"azdata_cell_guid": "075fb2ba-5a46-46b9-8ab3-9b9dbc7943dd"
}
},
{
"cell_type": "code",
"source": [
"Get-Secret -Name ASecretFromMe -AsPlainText\r\n",
""
],
"metadata": {
"azdata_cell_guid": "5b9bbb26-0713-4ae4-b3cd-90f812be7efe"
},
"outputs": [
{
"name": "stdout",
"text": "I_got_my_first_tattoo_in_my_30s\r\n",
"output_type": "stream"
}
],
"execution_count": 1
},
{
"cell_type": "markdown",
"source": [
"You can create PsCredentialObjects using the secrets"
],
"metadata": {
"azdata_cell_guid": "0c89e3d6-2ba2-4eae-a42b-96b8256109f5"
}
},
{
"cell_type": "code",
"source": [
"$secretName = 'ASurprisingFact'\r\n",
"$Secret = Get-Secret -Name $secretName\r\n",
"$credential = New-Object System.Management.Automation.PSCredential ($secretName, $secret)\r\n",
"$credential"
],
"metadata": {
"azdata_cell_guid": "737267bc-43c2-462f-8546-30734db6b4a6"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": "\r\n"
},
{
"output_type": "stream",
"name": "stdout",
"text": "UserName Password\r\n"
},
{
"output_type": "stream",
"name": "stdout",
"text": "-------- --------\r\n"
},
{
"output_type": "stream",
"name": "stdout",
"text": "ASurprisingFact System.Security.SecureString\r\n"
},
{
"output_type": "stream",
"name": "stdout",
"text": "\r\n"
}
],
"execution_count": 14
},
{
"cell_type": "markdown",
"source": [
"You can always reveal the password in a PSCredential object with"
],
"metadata": {
"azdata_cell_guid": "aaf43927-e380-42be-a39b-adf3ea5f08af"
}
},
{
"cell_type": "code",
"source": [
"$credential.GetNetworkCredential().Password"
],
"metadata": {
"azdata_cell_guid": "f2cc774b-5893-4d4f-ad10-61c444893363"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": "Isaac_Newton_invented_the_cat_door\r\n"
}
],
"execution_count": 16
},
{
"cell_type": "markdown",
"source": [
"## Updating Secrets\r\n",
"\r\n",
"You update secrets using `Set-Secret`"
],
"metadata": {
"azdata_cell_guid": "bfd433d8-8605-4fc6-abea-9d5e9c09151e"
}
},
{
"cell_type": "code",
"source": [
"Set-Secret -Name ASurprisingFact -Secret 'A house cat can reach speeds of up to 30mph'\r\n",
"\r\n",
"$secretName = 'ASurprisingFact'\r\n",
"$Secret = Get-Secret -Name $secretName\r\n",
"$credential = New-Object System.Management.Automation.PSCredential ($secretName, $secret)\r\n",
"$credential.GetNetworkCredential().Password"
],
"metadata": {
"azdata_cell_guid": "a8af74a8-ae74-4060-ad70-e865a1a7a3df"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": "A house cat can reach speeds of up to 30mph\r\n"
}
],
"execution_count": 20
},
{
"cell_type": "markdown",
"source": [
"## Listing Secrets\r\n",
"\r\n",
"You can list the secrets in the vault with `Get-SecretInfo` You can see the type of secret and the secrets int he vault that the user has access to."
],
"metadata": {
"azdata_cell_guid": "68902267-5dc1-4b3f-852b-6ab8d1f4ede2"
}
},
{
"cell_type": "code",
"source": [
"Get-SecretInfo"
],
"metadata": {
"azdata_cell_guid": "a543de1d-f0f9-42f3-8c15-408cbe27e601"
},
"outputs": [
{
"name": "stdout",
"text": "\r\n",
"output_type": "stream"
},
{
"name": "stdout",
"text": "Name Type VaultName\r\n",
"output_type": "stream"
},
{
"name": "stdout",
"text": "---- ---- ---------\r\n",
"output_type": "stream"
},
{
"name": "stdout",
"text": "ASecretFromMe SecureString BuiltInLocalVault\r\n",
"output_type": "stream"
},
{
"name": "stdout",
"text": "ASurpringFact String BuiltInLocalVault\r\n",
"output_type": "stream"
},
{
"name": "stdout",
"text": "ASurprisingFact String BuiltInLocalVault\r\n",
"output_type": "stream"
},
{
"name": "stdout",
"text": "MyAwesomeSecret String BuiltInLocalVault\r\n",
"output_type": "stream"
},
{
"name": "stdout",
"text": "\r\n",
"output_type": "stream"
}
],
"execution_count": 2
},
{
"cell_type": "markdown",
"source": [
"## Removing Secrets\r\n",
"\r\n",
"You can remove secrets with `Remove-Secret` As you can see above, I mistyped when creating this notebook and created a secret called `ASurpringFact` Lets remove that one, you have to specify the vaultname\r\n",
"\r\n",
""
],
"metadata": {
"azdata_cell_guid": "6813da34-10d8-4be3-8204-ab5a95856255"
}
},
{
"cell_type": "code",
"source": [
"Remove-Secret ASurpringFact -Vault BuiltInLocalVault "
],
"metadata": {
"azdata_cell_guid": "5f60b601-0420-47b3-a7eb-6bfad5c78e5a"
},
"outputs": [],
"execution_count": 3
},
{
"cell_type": "markdown",
"source": [
"and when we check it is gone"
],
"metadata": {
"azdata_cell_guid": "b25cea41-1969-4fae-8f35-00695e36c0a8"
}
},
{
"cell_type": "code",
"source": [
"Get-SecretInfo"
],
"metadata": {
"azdata_cell_guid": "1bc4d3b9-0309-47ba-9ea0-ba62522b1415"
},
"outputs": [
{
"name": "stdout",
"text": "\r\n",
"output_type": "stream"
},
{
"name": "stdout",
"text": "Name Type VaultName\r\n",
"output_type": "stream"
},
{
"name": "stdout",
"text": "---- ---- ---------\r\n",
"output_type": "stream"
},
{
"name": "stdout",
"text": "ASecretFromMe SecureString BuiltInLocalVault\r\n",
"output_type": "stream"
},
{
"name": "stdout",
"text": "ASurprisingFact String BuiltInLocalVault\r\n",
"output_type": "stream"
},
{
"name": "stdout",
"text": "MyAwesomeSecret String BuiltInLocalVault\r\n",
"output_type": "stream"
},
{
"name": "stdout",
"text": "\r\n",
"output_type": "stream"
}
],
"execution_count": 4
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment