[{"data":1,"prerenderedAt":640},["Reactive",2],{"navigation":3,"/posts/w22-2021-tips-learned-this-week":204,"/posts/w22-2021-tips-learned-this-week-surround":609},[4,192,200],{"title":5,"_path":6,"children":7,"icon":191},"Blog","/posts",[8,11,14,17,20,23,26,29,32,35,38,41,44,47,50,53,56,59,62,65,68,71,74,77,80,83,86,89,92,95,98,101,104,107,110,113,116,119,122,125,128,131,134,137,140,143,146,149,152,155,158,161,164,167,170,173,176,179,182,185,188],{"title":9,"_path":10},"Testing your API with REST Client","/posts/testing-your-api-with-rest-client",{"title":12,"_path":13},"HTML templating in Xamarin","/posts/html-templating-in-xamarin",{"title":15,"_path":16},"Goodbye Azure Portal, Welcome Azure CLI","/posts/welcome-azure-cli",{"title":18,"_path":19},"Coming across Gitpod","/posts/gitpod",{"title":21,"_path":22},"Handle token retrieval while querying an API","/posts/delegating-handler",{"title":24,"_path":25},"Clean up your local git branches.","/posts/cleaning-git-branches",{"title":27,"_path":28},"Automate configuration of Teams Tab SSO with PowerShell.","/posts/teams-sso-powershell",{"title":30,"_path":31},"How to do a technology watch? - Part 1","/posts/technology-watch-part1",{"title":33,"_path":34},"How to do a technology watch? - Part 2","/posts/technology-watch-part2",{"title":36,"_path":37},"You almost no longer need Key Vault references for Azure Functions.","/posts/azure-functions-custom-configuration",{"title":39,"_path":40},"How to do a technology watch? - Part 3","/posts/technology-watch-part3",{"title":42,"_path":43},"Forget DevOps, the future is already here!","/posts/devops-future",{"title":45,"_path":46},"Week 9, 2021 - Tips I learned this week","/posts/w09-2021-tips-learned-this-week",{"title":48,"_path":49},"Week 12, 2021 - Tips I learned this week","/posts/w12-2021-tips-learned-this-week",{"title":51,"_path":52},"Week 14, 2021 - Tips I learned this week","/posts/w14-2021-tips-learned-this-week",{"title":54,"_path":55},"Once upon a time in .NET","/posts/once-upon-a-time-in-dotnet",{"title":57,"_path":58},"Install your applications with winget","/posts/winget-import",{"title":60,"_path":61},"Customize your applications when installing them with winget","/posts/winget-override",{"title":63,"_path":64},"Week 22, 2021 - Tips I learned this week","/posts/w22-2021-tips-learned-this-week",{"title":66,"_path":67},"How to connect to an Azure SQL Database from C# using Azure AD","/posts/sqlclient-active-directory-authent",{"title":69,"_path":70},"Producing packages for Windows Package Manager","/posts/wingetcreate",{"title":72,"_path":73},"4 tips about GitHub Actions environment variables and contexts","/posts/github-actions-var-and-context",{"title":75,"_path":76},"AzureWebJobsStorage, the secret you don't need in your Function App.","/posts/azure-functions-without-azurewebjobsstorage",{"title":78,"_path":79},"ASP.NET Core - Lost in configuration","/posts/lost-in-configuration",{"title":81,"_path":82},"Week 39, 2021 - Tips I learned this week","/posts/w39-2021-tips-learned-this-week",{"title":84,"_path":85},"Week 41, 2021 - Tips I learned this week","/posts/w41-2021-tips-learned-this-week",{"title":87,"_path":88},"Migrating and open-sourcing my blog","/posts/migrating-blog",{"title":90,"_path":91},"Week 45, 2021 - Tips I learned this week","/posts/w45-2021-tips-learned-this-week",{"title":93,"_path":94},"Organize your GitHub stars with Astral","/posts/astral",{"title":96,"_path":97},"Pulumi with an Azure Blob Storage backend","/posts/pulumi-azure-backend",{"title":99,"_path":100},"IaC Hot Reload with Pulumi Watch","/posts/pulumi-watch",{"title":102,"_path":103},"Week 2, 2022 - Tips I learned this week","/posts/w02-2022-tips-learned-this-week",{"title":105,"_path":106},"Week 3, 2022 - Tips I learned this week","/posts/w03-2022-tips-learned-this-week",{"title":108,"_path":109},"Week 5, 2022 - Tips I learned this week","/posts/w05-2022-tips-learned-this-week",{"title":111,"_path":112},"How to provision an Azure SQL Database with Active Directory authentication","/posts/sqldatabase-active-directory-authent",{"title":114,"_path":115},"Why will I choose Pulumi over Terraform for my next project?","/posts/pulumi-vs-terraform",{"title":117,"_path":118},"Week 19, 2022 - Tips I learned this week","/posts/w19-2022-tips-learned-this-week",{"title":120,"_path":121},"Week 20, 2022 - Tips I learned this week","/posts/w20-2022-tips-learned-this-week",{"title":123,"_path":124},"Keeping secrets secure when using API Clients","/posts/http-clients-secrets",{"title":126,"_path":127},"What made me want to be a developer?","/posts/be-a-developer",{"title":129,"_path":130},"What can we do when stuck with a programming problem?","/posts/get-unstuck",{"title":132,"_path":133},"How did I automate the setup of my developer Windows laptop?","/posts/automate-developer-machine",{"title":135,"_path":136},"Discussion about API clients","/posts/http-clients",{"title":138,"_path":139},"Week 46, 2022 - Tips I learned this week","/posts/w46-2022-tips-learned-this-week",{"title":141,"_path":142},"When Pulumi met Nuke: a .NET love story","/posts/when-pulumi-met-nuke",{"title":144,"_path":145},"A year of learning and sharing - Dev Retro 2022","/posts/2022-retro",{"title":147,"_path":148},"Perform Dynamic Execution of an npm Package","/posts/pnpm-dlx",{"title":150,"_path":151},"Manage multiple Node.js versions","/posts/pnpm-env",{"title":153,"_path":154},"Introducing the Vue.js CI/CD series","/posts/vuecicd-introduction",{"title":156,"_path":157},"Execute commands using your project dependencies","/posts/pnpm-exec",{"title":159,"_path":160},"Vue.js CI/CD: Continuous Integration","/posts/vuecicd-ci",{"title":162,"_path":163},"Who is using pnpm?","/posts/pnpm-who-is-using",{"title":165,"_path":166},"Create an Azure-Ready GitHub Repository using Pulumi","/posts/azure-ready-github-repository",{"title":168,"_path":169},"Deploying to Azure from Azure DevOps without secrets","/posts/ado-workload-identity-federation",{"title":171,"_path":172},"Effortlessly Configure GitHub Repositories for Azure Deployment via OIDC","/posts/scripting-azure-ready-github-repository",{"title":174,"_path":175},"Playing with the .NET 8 Web API template","/posts/playing-with-dotnet8",{"title":177,"_path":178},"Another year of sharing and learning - Dev Retro 2023","/posts/2023-retro",{"title":180,"_path":181},"Week 4, 2024 - Tips I learned this week","/posts/w04-2024-tips-learned-this-week",{"title":183,"_path":184},"Using dependency injection with Azure .NET SDK","/posts/azure-sdk-di",{"title":186,"_path":187},"Having Fun With IT Event Calendars","/posts/it-event-calendars",{"title":189,"_path":190},"Call your Azure AD B2C protected API with authenticated HTTP requests from your JetBrains IDE","/posts/http-clients-oauth2","i-heroicons-newspaper",{"title":193,"_path":194,"children":195,"icon":199},"Goodies","/goodies",[196],{"title":197,"_path":198},"My Git Cheat Sheet","/goodies/gitcheatsheet","i-heroicons-gift-solid",{"title":201,"_path":202,"icon":203},"About","/about","i-heroicons-user-circle-solid",{"_path":64,"_dir":205,"_draft":206,"_partial":206,"_locale":207,"title":63,"description":208,"lead":209,"date":210,"image":211,"badge":213,"tags":215,"body":220,"_type":604,"_id":605,"_source":606,"_file":607,"_extension":608},"posts",false,"","This week I learned some Azure CLI commands, how to have JSON IntelliSense in vscode and that Azure Storage Explorer was usable again.","IntelliSense in vscode, Azure CLI command to get assigned roles, and Azure Storage Explorer new version.","2021-06-07T00:00:00.000Z",{"src":212},"/images/surface_1.jpg",{"label":214},"Tips",[216,217,218,219],"tips learned this week","vscode","Azure CLI","Azure",{"type":221,"children":222,"toc":598},"root",[223,230,237,242,256,268,273,289,295,315,324,352,372,414,419,550,556,568,573,582,587,592],{"type":224,"tag":225,"props":226,"children":227},"element","p",{},[228],{"type":229,"value":208},"text",{"type":224,"tag":231,"props":232,"children":234},"h2",{"id":233},"autocompletion-and-schema-validation-when-editing-a-json-file-in-vscode",[235],{"type":229,"value":236},"Autocompletion and schema validation when editing a JSON file in vscode.",{"type":224,"tag":225,"props":238,"children":239},{},[240],{"type":229,"value":241},"When you are editing a JSON file in vscode, chances are that there is a JSON schema somewhere that describes the shape of the JSON you are modifying. Wouldn't it be great if vscode could provide you suggestions and validate the JSON according to such a schema while you are typing ⌨?",{"type":224,"tag":225,"props":243,"children":244},{},[245,247,254],{"type":229,"value":246},"Well in fact it is possible, you just have to add at the beginning of your file a ",{"type":224,"tag":248,"props":249,"children":251},"code",{"className":250},[],[252],{"type":229,"value":253},"$schema",{"type":229,"value":255}," key (with the URI of the JSON schema as the value) and you will have IntelliSense to edit your JSON in vscode.",{"type":224,"tag":225,"props":257,"children":258},{},[259],{"type":224,"tag":260,"props":261,"children":267},"img",{"alt":262,"className":263,"src":266},"Json file in vscode.",[264,265],"rounded-lg","mx-auto","/posts/images/w222021tips_vscode_1.png",[],{"type":224,"tag":225,"props":269,"children":270},{},[271],{"type":229,"value":272},"In the screenshot above, I am editing a JSON file where the linked JSON schema is a Microsoft Teams app manifest schema, and as you can see vscode gives me suggestions based on this schema.",{"type":224,"tag":225,"props":274,"children":275},{},[276,278,287],{"type":229,"value":277},"This is a tip that you probably already know but as far as I am concerned I only discovered it recently and it is really useful. If you want to do more advanced things like mapping some files types to specific JSON schemas you can have a look in ",{"type":224,"tag":279,"props":280,"children":284},"a",{"href":281,"rel":282},"https://code.visualstudio.com/docs/languages/json#_json-schemas-and-settings",[283],"nofollow",[285],{"type":229,"value":286},"vscode documentation",{"type":229,"value":288},".",{"type":224,"tag":231,"props":290,"children":292},{"id":291},"listing-assigned-roles-for-a-user-on-a-subscription-with-azure-cli",[293],{"type":229,"value":294},"Listing assigned roles for a user on a subscription with Azure CLI",{"type":224,"tag":225,"props":296,"children":297},{},[298,300,313],{"type":229,"value":299},"I recently had to list all the roles assigned to my user on a subscription. 👮‍♀️\nFor that I used the ",{"type":224,"tag":279,"props":301,"children":304},{"href":302,"rel":303},"https://docs.microsoft.com/en-us/cli/azure/role/assignment?view=azure-cli-latest#az_role_assignment_list",[283],[305,311],{"type":224,"tag":248,"props":306,"children":308},{"className":307},[],[309],{"type":229,"value":310},"az role assignment list",{"type":229,"value":312}," command",{"type":229,"value":314}," like this:",{"type":224,"tag":225,"props":316,"children":317},{},[318],{"type":224,"tag":260,"props":319,"children":323},{"alt":320,"className":321,"src":322},"Terminal showing az role assigment command.",[264,265],"/posts/images/w222021tips_azcli_1.png",[],{"type":224,"tag":225,"props":325,"children":326},{},[327,329,335,337,343,345,351],{"type":229,"value":328},"I am filtering the command result with the ",{"type":224,"tag":248,"props":330,"children":332},{"className":331},[],[333],{"type":229,"value":334},"--query",{"type":229,"value":336}," argument to only have the information I am interested in which are ",{"type":224,"tag":248,"props":338,"children":340},{"className":339},[],[341],{"type":229,"value":342},"roleDefinitionName",{"type":229,"value":344}," and ",{"type":224,"tag":248,"props":346,"children":348},{"className":347},[],[349],{"type":229,"value":350},"scope",{"type":229,"value":288},{"type":224,"tag":225,"props":353,"children":354},{},[355,357,363,365,371],{"type":229,"value":356},"You can specify a subscription by using the optional parameter ",{"type":224,"tag":248,"props":358,"children":360},{"className":359},[],[361],{"type":229,"value":362},"--subscription",{"type":229,"value":364}," but by default, the subscription selected is the current subscription which you can see by doing an ",{"type":224,"tag":248,"props":366,"children":368},{"className":367},[],[369],{"type":229,"value":370},"az account show",{"type":229,"value":288},{"type":224,"tag":225,"props":373,"children":374},{},[375,377,383,385,391,393,399,401,412],{"type":229,"value":376},"The variable ",{"type":224,"tag":248,"props":378,"children":380},{"className":379},[],[381],{"type":229,"value":382},"UserId",{"type":229,"value":384}," which is passed to the option ",{"type":224,"tag":248,"props":386,"children":388},{"className":387},[],[389],{"type":229,"value":390},"--assignee",{"type":229,"value":392}," contains my user id but I could have also passed my user principal name. As I was looking to list my assigned roles on a subscription in a tenant id where I am a guest, my user principal name is a bit strange with an ",{"type":224,"tag":248,"props":394,"children":396},{"className":395},[],[397],{"type":229,"value":398},"#EXT#",{"type":229,"value":400}," in it so I can never remember what it is. And as I don't know by heart my user id either, I use the ",{"type":224,"tag":279,"props":402,"children":405},{"href":403,"rel":404},"https://docs.microsoft.com/en-us/cli/azure/ad/user?view=azure-cli-latest#az_ad_user_show",[283],[406],{"type":224,"tag":248,"props":407,"children":409},{"className":408},[],[410],{"type":229,"value":411},"az ad signed-in-user show",{"type":229,"value":413}," command to get my user id.",{"type":224,"tag":225,"props":415,"children":416},{},[417],{"type":229,"value":418},"So at the end my command to list the assigned roles to my user on the current subscription is the following:",{"type":224,"tag":420,"props":421,"children":425},"pre",{"className":422,"code":423,"language":424,"meta":207,"style":207},"language-powershell shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","az role assignment list --assignee $(az ad signed-in-user show --query \"objectId\") --query \"[*].{role:roleDefinitionName,scope:scope}\" --include-inherited\n","powershell",[426],{"type":224,"tag":248,"props":427,"children":428},{"__ignoreMap":207},[429],{"type":224,"tag":430,"props":431,"children":434},"span",{"class":432,"line":433},"line",1,[435,441,447,452,457,462,467,472,476,481,485,490,495,501,505,510,515,519,523,528,532,536,541,545],{"type":224,"tag":430,"props":436,"children":438},{"style":437},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[439],{"type":229,"value":440},"az role assignment list ",{"type":224,"tag":430,"props":442,"children":444},{"style":443},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[445],{"type":229,"value":446},"--",{"type":224,"tag":430,"props":448,"children":449},{"style":437},[450],{"type":229,"value":451},"assignee ",{"type":224,"tag":430,"props":453,"children":454},{"style":443},[455],{"type":229,"value":456},"$(",{"type":224,"tag":430,"props":458,"children":459},{"style":437},[460],{"type":229,"value":461},"az ad signed",{"type":224,"tag":430,"props":463,"children":464},{"style":443},[465],{"type":229,"value":466},"-",{"type":224,"tag":430,"props":468,"children":469},{"style":437},[470],{"type":229,"value":471},"in",{"type":224,"tag":430,"props":473,"children":474},{"style":443},[475],{"type":229,"value":466},{"type":224,"tag":430,"props":477,"children":478},{"style":437},[479],{"type":229,"value":480},"user show ",{"type":224,"tag":430,"props":482,"children":483},{"style":443},[484],{"type":229,"value":446},{"type":224,"tag":430,"props":486,"children":487},{"style":437},[488],{"type":229,"value":489},"query ",{"type":224,"tag":430,"props":491,"children":492},{"style":443},[493],{"type":229,"value":494},"\"",{"type":224,"tag":430,"props":496,"children":498},{"style":497},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[499],{"type":229,"value":500},"objectId",{"type":224,"tag":430,"props":502,"children":503},{"style":443},[504],{"type":229,"value":494},{"type":224,"tag":430,"props":506,"children":507},{"style":443},[508],{"type":229,"value":509},")",{"type":224,"tag":430,"props":511,"children":512},{"style":443},[513],{"type":229,"value":514}," --",{"type":224,"tag":430,"props":516,"children":517},{"style":437},[518],{"type":229,"value":489},{"type":224,"tag":430,"props":520,"children":521},{"style":443},[522],{"type":229,"value":494},{"type":224,"tag":430,"props":524,"children":525},{"style":497},[526],{"type":229,"value":527},"[*].{role:roleDefinitionName,scope:scope}",{"type":224,"tag":430,"props":529,"children":530},{"style":443},[531],{"type":229,"value":494},{"type":224,"tag":430,"props":533,"children":534},{"style":443},[535],{"type":229,"value":514},{"type":224,"tag":430,"props":537,"children":538},{"style":437},[539],{"type":229,"value":540},"include",{"type":224,"tag":430,"props":542,"children":543},{"style":443},[544],{"type":229,"value":466},{"type":224,"tag":430,"props":546,"children":547},{"style":437},[548],{"type":229,"value":549},"inherited\n",{"type":224,"tag":231,"props":551,"children":553},{"id":552},"azure-storage-explorer-just-got-better",[554],{"type":229,"value":555},"Azure Storage Explorer just got better!",{"type":224,"tag":225,"props":557,"children":558},{},[559,566],{"type":224,"tag":279,"props":560,"children":563},{"href":561,"rel":562},"https://azure.microsoft.com/en-us/features/storage-explorer/",[283],[564],{"type":229,"value":565},"Azure Storage Explorer",{"type":229,"value":567}," is a tool to manage your Azure cloud storage resources from your desktop. Instead of going to the Azure portal and navigating between all the panes and resources, you can do everything from this tool like viewing the tables and blobs in the storage accounts you have access to.",{"type":224,"tag":225,"props":569,"children":570},{},[571],{"type":229,"value":572},"Unfortunately, if your account had access to multiple subscriptions on multiple tenants with MFA enabled, using Azure Storage Explorer was a nightmare where you had to log in to every tenant multiple times to access any storage account. If you had the correct permissions you ended up grabbing a secret connection string to access your storage account from Azure Storage Explorer but it was not a good solution (using secrets instead of your Azure AD account to access resources is never a good idea ⛔).",{"type":224,"tag":225,"props":574,"children":575},{},[576],{"type":224,"tag":260,"props":577,"children":581},{"alt":578,"className":579,"src":580},"Azure Storage Explorer account management section.",[264,265],"/posts/images/w222021tips_storageexplorer_1.png",[],{"type":224,"tag":225,"props":583,"children":584},{},[585],{"type":229,"value":586},"As you can see on the screenshot above, in v1.19.x Azure Storage Explorer account management section has been completely refreshed to allow us to control exactly the tenants and the subscriptions that we want to load. This way we only have to enter the credentials we need and Azure Storage Explorer becomes usable again! 🎉",{"type":224,"tag":225,"props":588,"children":589},{},[590],{"type":229,"value":591},"And that's it for this week, happy learning!",{"type":224,"tag":593,"props":594,"children":595},"style",{},[596],{"type":229,"value":597},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":207,"searchDepth":599,"depth":599,"links":600},2,[601,602,603],{"id":233,"depth":599,"text":236},{"id":291,"depth":599,"text":294},{"id":552,"depth":599,"text":555},"markdown","content:1.posts:19.w22-2021-tips-learned-this-week.md","content","1.posts/19.w22-2021-tips-learned-this-week.md","md",[610,625],{"_path":67,"_dir":205,"_draft":206,"_partial":206,"_locale":207,"title":66,"description":611,"lead":612,"date":613,"image":614,"badge":616,"tags":618,"_type":604,"_id":623,"_source":606,"_file":624,"_extension":608},"In Microsoft.Data.SqlClient v3.0.0, a new authentication mode Active Directory Default has been released. Let's see what this means when querying an Azure SQL Database from some C# code.","Talking about Active Directory Default authentication mode for SqlClient.","2021-06-22T00:00:00.000Z",{"src":615},"/images/cloud-azure_1.jpg",{"label":617},"Development",[619,620,621,219,218,622],"Azure Active Directory","Azure SQL Database","Azure SDK","ASP.NET Core","content:1.posts:20.sqlclient-active-directory-authent.md","1.posts/20.sqlclient-active-directory-authent.md",{"_path":61,"_dir":205,"_draft":206,"_partial":206,"_locale":207,"title":60,"description":626,"lead":627,"date":628,"image":629,"badge":631,"tags":633,"_type":604,"_id":638,"_source":606,"_file":639,"_extension":608},"In my last article about Windows Package Manager, I said that with winget I was missing \"being able to specify some parameters for a package installation (like the workload and components to install for Visual Studio 2019)\". Well, that was before I went through a few GitHub issues of the winget-cli repository that mentioned the override option.","The override option of winget install command","2021-05-31T00:00:00.000Z",{"src":630},"/images/surface_2.jpg",{"label":632},"Tooling",[634,635,636,637],"development box setup","winget","package manager","tooling","content:1.posts:18.winget-override.md","1.posts/18.winget-override.md",1716749601642]