[{"data":1,"prerenderedAt":6664},["Reactive",2],{"navigation":3,"aAII9Cz3yR":204,"tags-PowerShell":397},[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",[205,207,209,211,214,217,220,223,226,229,231,234,237,240,242,244,247,250,253,255,258,261,264,267,270,273,276,279,282,285,287,289,292,294,297,300,303,305,308,310,313,316,319,322,325,327,329,332,335,338,341,344,347,350,353,356,359,361,363,366,369,372,375,377,380,383,385,388,391,394],[206,206],"tooling",[208,208],"vscode",[210,210],"rest",[212,213],"http","HTTP",[215,216],"razor","Razor",[218,219],"xamarin","Xamarin",[221,222],"templating","Templating",[224,225],"azure-cli","Azure CLI",[227,228],"azure","Azure",[230,230],"shell",[232,233],"github","GitHub",[235,236],"asp-net-core","ASP.NET Core",[238,239],"net",".NET",[241,241],"git",[243,243],"nushell",[245,246],"microsoft-teams","Microsoft Teams",[248,249],"powershell","PowerShell",[251,252],"azure-active-directory","Azure Active Directory",[254,254],"learning",[256,257],"azure-functions","Azure Functions",[259,260],"azure-key-vault","Azure Key Vault",[262,263],"configuration","Configuration",[265,266],"devops","DevOps",[268,269],"it","IT",[271,272],"tips-learned-this-week","tips learned this week",[274,275],"windows-terminal","Windows Terminal",[277,278],"azure-pipelines","Azure Pipelines",[280,281],"application-insights","Application Insights",[283,284],"azure-iot","Azure IoT",[286,286],"records",[288,288],"refit",[290,291],"development-box-setup","development box setup",[293,293],"winget",[295,296],"package-manager","package manager",[298,299],"azure-sql-database","Azure SQL Database",[301,302],"azure-sdk","Azure SDK",[304,304],"wingetcreate",[306,307],"github-actions","GitHub Actions",[309,309],"jq",[311,312],"pulumi","Pulumi",[314,315],"iac","IaC",[317,318],"azure-storage","Azure Storage",[320,321],"azure-signalr","Azure SignalR",[323,324],"visio","Visio",[326,326],"csharp",[328,328],"jest",[330,331],"statiq","Statiq",[333,334],"open-source","open source",[336,337],"visual-studio","Visual Studio",[339,340],"vue-js","Vue.js",[342,343],"azure-devops","Azure DevOps",[345,346],"vite","Vite",[348,349],"code-analysis","Code analysis",[351,352],"diagram","Diagram",[354,355],"terraform","Terraform",[357,358],"typescript","TypeScript",[360,360],"thoughts",[362,362],"pnpm",[364,365],"nuke","Nuke",[367,368],"pipelines","Pipelines",[370,371],"cicd","CI/CD",[373,374],"openid-connect","OpenID Connect",[376,376],"security",[378,379],"github-cli","GitHub CLI",[381,382],"microsoft-entra-id","Microsoft Entra ID",[384,384],"advent",[386,387],"finops","FinOps",[389,390],"anglesharp","AngleSharp",[392,393],"oauth2","OAuth2",[395,396],"azure-ad-b2c","Azure AD B2C",[398,1980,2616],{"_path":133,"_dir":399,"_draft":400,"_partial":400,"_locale":401,"title":132,"description":402,"lead":403,"date":404,"badge":405,"image":407,"tags":409,"body":410,"_type":1975,"_id":1976,"_source":1977,"_file":1978,"_extension":1979},"posts",false,"","In this article, I talked about my latest project: how I built a script to automate the setup of my developer machine using Boxstarter, Chocolatey, Winget, and PowerShell... and how I learned a few things along the way.","A git repository, 2 packages managers, a little bit of scripting, and here is my new environment ready","2022-09-02T00:00:00.000Z",{"label":406},"Tooling",{"src":408},"/images/laptop_2.jpg",[291,249,293,296,206],{"type":411,"children":412,"toc":1962},"root",[413,420,427,432,437,449,454,479,485,490,515,547,568,598,607,617,637,642,772,784,790,797,819,824,841,847,852,861,866,871,955,963,968,982,996,1002,1024,1062,1067,1337,1360,1365,1413,1421,1427,1432,1623,1643,1649,1654,1663,1668,1718,1730,1807,1812,1817,1823,1828,1850,1864,1869,1896,1910,1916,1928,1933,1938,1951,1956],{"type":414,"tag":415,"props":416,"children":417},"element","p",{},[418],{"type":419,"value":402},"text",{"type":414,"tag":421,"props":422,"children":424},"h2",{"id":423},"context",[425],{"type":419,"value":426},"Context",{"type":414,"tag":415,"props":428,"children":429},{},[430],{"type":419,"value":431},"You have probably already faced this situation when you get a new personal or professional laptop, and you have to reinstall all the software you are using daily on this machine. Usually, you lose a few hours to a day to set up your developer environment and not everything is exactly as it was on your previous laptop because you always forget some things.",{"type":414,"tag":415,"props":433,"children":434},{},[435],{"type":419,"value":436},"It's not even only about installing software but also configuring your environment to meet your habits. And that's important because a properly configured developer environment with the right tools is what makes you productive in your everyday developer life.",{"type":414,"tag":415,"props":438,"children":439},{},[440],{"type":414,"tag":441,"props":442,"children":448},"img",{"alt":443,"className":444,"src":447},"A collection of office supplies laid out on a table.",[445,446],"rounded-lg","mx-auto","/posts/images/automate_developer_machine_tool.jpg",[],{"type":414,"tag":415,"props":450,"children":451},{},[452],{"type":419,"value":453},"A lot of people have solved this issue by scripting their developer environment setup, and I decided it was time for me to do the same. And believe me, it was not for the beauty of having everything automatically installed but to stop wasting my time each time I change or reinstall my laptop.",{"type":414,"tag":415,"props":455,"children":456},{},[457,459,468,470,477],{"type":419,"value":458},"Please note that what I did to setup my developer machine was inspired by the ",{"type":414,"tag":460,"props":461,"children":465},"a",{"href":462,"rel":463},"https://github.com/Microsoft/windows-dev-box-setup-scripts",[464],"nofollow",[466],{"type":419,"value":467},"Windows Dev Box setup scripts",{"type":419,"value":469}," GitHub repository and other repositories using boxstarter (check ",{"type":414,"tag":460,"props":471,"children":474},{"href":472,"rel":473},"https://github.com/laurentkempe/Cacao",[464],[475],{"type":419,"value":476},"Laurent Kempé's repository",{"type":419,"value":478}," for instance) to install their Windows environment.",{"type":414,"tag":421,"props":480,"children":482},{"id":481},"how-does-it-work",[483],{"type":419,"value":484},"How does it work?",{"type":414,"tag":415,"props":486,"children":487},{},[488],{"type":419,"value":489},"There are many ways to automate the setup of a developer machine. Before choosing one, I had a few requirements/preferences:",{"type":414,"tag":491,"props":492,"children":493},"ul",{},[494,500,505,510],{"type":414,"tag":495,"props":496,"children":497},"li",{},[498],{"type":419,"value":499},"installation of my machine should be simple to script and run",{"type":414,"tag":495,"props":501,"children":502},{},[503],{"type":419,"value":504},"no need to pre-install some software before launching the installation of my environment",{"type":414,"tag":495,"props":506,"children":507},{},[508],{"type":419,"value":509},"avoid manual steps or user interaction during the installation",{"type":414,"tag":495,"props":511,"children":512},{},[513],{"type":419,"value":514},"be able easily to share some software configurations between laptops",{"type":414,"tag":415,"props":516,"children":517},{},[518,520,527,529,536,538,545],{"type":419,"value":519},"Because of these requirements, I chose to use ",{"type":414,"tag":460,"props":521,"children":524},{"href":522,"rel":523},"https://boxstarter.org/",[464],[525],{"type":419,"value":526},"Boxstarter",{"type":419,"value":528},". It has several interesting features (check the ",{"type":414,"tag":460,"props":530,"children":533},{"href":531,"rel":532},"https://boxstarter.org/whyboxstarter",[464],[534],{"type":419,"value":535},"website",{"type":419,"value":537},") but the one I like the most is you can launch your installation process directly by ",{"type":414,"tag":460,"props":539,"children":542},{"href":540,"rel":541},"https://boxstarter.org/weblauncher",[464],[543],{"type":419,"value":544},"clicking on a link",{"type":419,"value":546},". You just need an URL like this one:",{"type":414,"tag":548,"props":549,"children":552},"pre",{"className":550,"code":551,"language":212,"meta":401,"style":401},"language-http shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","https://boxstarter.org/package/nr/url?{urlToYourInstallationScript}\n",[553],{"type":414,"tag":554,"props":555,"children":556},"code",{"__ignoreMap":401},[557],{"type":414,"tag":558,"props":559,"children":562},"span",{"class":560,"line":561},"line",1,[563],{"type":414,"tag":558,"props":564,"children":566},{"style":565},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[567],{"type":419,"value":551},{"type":414,"tag":415,"props":569,"children":570},{},[571,573,579,581,588,590,596],{"type":419,"value":572},"The ",{"type":414,"tag":554,"props":574,"children":576},{"className":575},[],[577],{"type":419,"value":578},"{urlToYourInstallationScript}",{"type":419,"value":580}," part is the URL where is stored your installation script. I put mine in a ",{"type":414,"tag":460,"props":582,"children":585},{"href":583,"rel":584},"https://github.com/TechWatching/dotfiles/blob/main/boxstarter.ps1",[464],[586],{"type":419,"value":587},"public GitHub repository",{"type":419,"value":589}," called ",{"type":414,"tag":554,"props":591,"children":593},{"className":592},[],[594],{"type":419,"value":595},"dotfiles",{"type":419,"value":597},".",{"type":414,"tag":415,"props":599,"children":600},{},[601],{"type":414,"tag":441,"props":602,"children":606},{"alt":603,"className":604,"src":605},"Boxstarter website.",[445,446],"/posts/images/automate_developer_machine_boxstarter.png",[],{"type":414,"tag":608,"props":609,"children":611},"callout",{"icon":610},"i-heroicons-chat-bubble-left-20-solid",[612],{"type":414,"tag":415,"props":613,"children":614},{},[615],{"type":419,"value":616},"Boxstarter was a nice discovery, I barely scratched the surface but it can do interesting things like remote installations.",{"type":414,"tag":415,"props":618,"children":619},{},[620,622,628,630,635],{"type":419,"value":621},"In this repository, I also put different scripts (to separate the different steps instead of having one big installation script file), some config files I wanted to use in my setup (my ",{"type":414,"tag":554,"props":623,"children":625},{"className":624},[],[626],{"type":419,"value":627},".gitconfig",{"type":419,"value":629}," file for instance), and a readme with some explanations and the link to launch the installation. I did not reinvent the wheel as it's more or less how the ",{"type":414,"tag":460,"props":631,"children":633},{"href":462,"rel":632},[464],[634],{"type":419,"value":467},{"type":419,"value":636}," work.",{"type":414,"tag":415,"props":638,"children":639},{},[640],{"type":419,"value":641},"Because I wanted to share some software configurations between laptops (or between installations), using a GitHub repository is interesting. The first thing my setup script does is to install Git, then it clones this repository to have access to the other scripts and configuration files.",{"type":414,"tag":548,"props":643,"children":646},{"className":644,"code":645,"language":248,"meta":401,"style":401},"language-powershell shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# Install git and clone repository containing scripts and config files\nchoco install -y git --params \"/GitOnlyOnPath /NoShellIntegration /WindowsTerminal\"\nRefreshEnv\ngit clone https://github.com/TechWatching/dotfiles.git \"$env:USERPROFILE\\dotfiles\"\n",[647],{"type":414,"tag":554,"props":648,"children":649},{"__ignoreMap":401},[650,659,705,714],{"type":414,"tag":558,"props":651,"children":652},{"class":560,"line":561},[653],{"type":414,"tag":558,"props":654,"children":656},{"style":655},"--shiki-light:#90A4AE;--shiki-default:#546E7A;--shiki-dark:#676E95;--shiki-light-font-style:italic;--shiki-default-font-style:italic;--shiki-dark-font-style:italic",[657],{"type":419,"value":658},"# Install git and clone repository containing scripts and config files\n",{"type":414,"tag":558,"props":660,"children":662},{"class":560,"line":661},2,[663,668,674,679,684,689,694,700],{"type":414,"tag":558,"props":664,"children":665},{"style":565},[666],{"type":419,"value":667},"choco install ",{"type":414,"tag":558,"props":669,"children":671},{"style":670},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[672],{"type":419,"value":673},"-",{"type":414,"tag":558,"props":675,"children":676},{"style":565},[677],{"type":419,"value":678},"y git ",{"type":414,"tag":558,"props":680,"children":681},{"style":670},[682],{"type":419,"value":683},"--",{"type":414,"tag":558,"props":685,"children":686},{"style":565},[687],{"type":419,"value":688},"params ",{"type":414,"tag":558,"props":690,"children":691},{"style":670},[692],{"type":419,"value":693},"\"",{"type":414,"tag":558,"props":695,"children":697},{"style":696},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[698],{"type":419,"value":699},"/GitOnlyOnPath /NoShellIntegration /WindowsTerminal",{"type":414,"tag":558,"props":701,"children":702},{"style":670},[703],{"type":419,"value":704},"\"\n",{"type":414,"tag":558,"props":706,"children":708},{"class":560,"line":707},3,[709],{"type":414,"tag":558,"props":710,"children":711},{"style":565},[712],{"type":419,"value":713},"RefreshEnv\n",{"type":414,"tag":558,"props":715,"children":717},{"class":560,"line":716},4,[718,723,728,734,739,744,748,753,758,763,768],{"type":414,"tag":558,"props":719,"children":720},{"style":565},[721],{"type":419,"value":722},"git clone https:",{"type":414,"tag":558,"props":724,"children":725},{"style":670},[726],{"type":419,"value":727},"//",{"type":414,"tag":558,"props":729,"children":731},{"style":730},"--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF",[732],{"type":419,"value":733},"github.com",{"type":414,"tag":558,"props":735,"children":736},{"style":670},[737],{"type":419,"value":738},"/",{"type":414,"tag":558,"props":740,"children":741},{"style":565},[742],{"type":419,"value":743},"TechWatching",{"type":414,"tag":558,"props":745,"children":746},{"style":670},[747],{"type":419,"value":738},{"type":414,"tag":558,"props":749,"children":750},{"style":565},[751],{"type":419,"value":752},"dotfiles.git ",{"type":414,"tag":558,"props":754,"children":755},{"style":670},[756],{"type":419,"value":757},"\"$",{"type":414,"tag":558,"props":759,"children":760},{"style":565},[761],{"type":419,"value":762},"env:USERPROFILE",{"type":414,"tag":558,"props":764,"children":765},{"style":696},[766],{"type":419,"value":767},"\\dotfiles",{"type":414,"tag":558,"props":769,"children":770},{"style":670},[771],{"type":419,"value":704},{"type":414,"tag":415,"props":773,"children":774},{},[775,777,783],{"type":419,"value":776},"The scripts are written in ",{"type":414,"tag":460,"props":778,"children":781},{"href":779,"rel":780},"https://docs.microsoft.com/en-us/powershell/",[464],[782],{"type":419,"value":249},{"type":419,"value":597},{"type":414,"tag":421,"props":785,"children":787},{"id":786},"installing-software",[788],{"type":419,"value":789},"Installing software",{"type":414,"tag":791,"props":792,"children":794},"h3",{"id":793},"package-managers",[795],{"type":419,"value":796},"Package managers",{"type":414,"tag":415,"props":798,"children":799},{},[800,802,809,811,818],{"type":419,"value":801},"The easiest way to automate installing, upgrading, and configuring software is to use package managers. There are several available on Windows but I chose to use ",{"type":414,"tag":460,"props":803,"children":806},{"href":804,"rel":805},"https://docs.microsoft.com/en-us/windows/package-manager/",[464],[807],{"type":419,"value":808},"Windows Package Manager",{"type":419,"value":810}," and ",{"type":414,"tag":460,"props":812,"children":815},{"href":813,"rel":814},"https://chocolatey.org/",[464],[816],{"type":419,"value":817},"Chocolatey",{"type":419,"value":597},{"type":414,"tag":415,"props":820,"children":821},{},[822],{"type":419,"value":823},"Windows Package Manager (aka winget) is relatively new so has fewer features and packages available than other package managers like Chocolatey. However it's very promising, it's getting better every day, it's built-in Windows, and above all, it supports installing Microsoft Store apps. So I chose to use winget by default and fallback to Chocolatey when a package I needed was not available or not up-to-date in winget.",{"type":414,"tag":608,"props":825,"children":826},{"icon":610},[827],{"type":414,"tag":415,"props":828,"children":829},{},[830,832,839],{"type":419,"value":831},"I learned a few things about winget while starting to use it. You can find my articles talking about it ",{"type":414,"tag":460,"props":833,"children":836},{"href":834,"rel":835},"https://www.techwatching.dev/tags/winget/",[464],[837],{"type":419,"value":838},"here",{"type":419,"value":840}," if you are interested.",{"type":414,"tag":791,"props":842,"children":844},{"id":843},"installing-integrated-development-environments-ides",[845],{"type":419,"value":846},"Installing Integrated Development Environments (IDEs)",{"type":414,"tag":415,"props":848,"children":849},{},[850],{"type":419,"value":851},"Visual Studio has been my main IDE for a while, but I have been started recently to use more and more Rider as well. Both are nice IDEs with many features particularly well suited for .NET development which is what I mostly do. I have been a Visual Studio Code long-time user too, mostly using it as a text editor or for front development. I also use vscode to work with Azure because it has nice extensions for a lot of Azure services.",{"type":414,"tag":415,"props":853,"children":854},{},[855],{"type":414,"tag":441,"props":856,"children":860},{"alt":857,"className":858,"src":859},"Visual Studio logo.",[445,446],"/posts/images/automate_developer_machine_visualstudio.jpg",[],{"type":414,"tag":415,"props":862,"children":863},{},[864],{"type":419,"value":865},"You probably want to customize your Visual Studio installation to only include the workloads, components, and language packs you are using. You can specify them as parameters in the winget or chocolatey install command but that's a bit cumbersome. The easiest way is to export your configuration from the Visual Studio installer.",{"type":414,"tag":415,"props":867,"children":868},{},[869],{"type":419,"value":870},"You can then install Visual Studio with this kind of command:",{"type":414,"tag":548,"props":872,"children":874},{"className":644,"code":873,"language":248,"meta":401,"style":401},"winget install -e -h --id Microsoft.VisualStudio.2022.Enterprise --silent --override \"--wait --quiet --addProductLang En-us --config .vsconfig\"\n",[875],{"type":414,"tag":554,"props":876,"children":877},{"__ignoreMap":401},[878],{"type":414,"tag":558,"props":879,"children":880},{"class":560,"line":561},[881,886,890,895,899,904,908,913,919,924,928,933,937,942,946,951],{"type":414,"tag":558,"props":882,"children":883},{"style":565},[884],{"type":419,"value":885},"winget install ",{"type":414,"tag":558,"props":887,"children":888},{"style":670},[889],{"type":419,"value":673},{"type":414,"tag":558,"props":891,"children":892},{"style":565},[893],{"type":419,"value":894},"e ",{"type":414,"tag":558,"props":896,"children":897},{"style":670},[898],{"type":419,"value":673},{"type":414,"tag":558,"props":900,"children":901},{"style":565},[902],{"type":419,"value":903},"h ",{"type":414,"tag":558,"props":905,"children":906},{"style":670},[907],{"type":419,"value":683},{"type":414,"tag":558,"props":909,"children":910},{"style":565},[911],{"type":419,"value":912},"id Microsoft.VisualStudio.",{"type":414,"tag":558,"props":914,"children":916},{"style":915},"--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C",[917],{"type":419,"value":918},"2022.",{"type":414,"tag":558,"props":920,"children":921},{"style":565},[922],{"type":419,"value":923},"Enterprise ",{"type":414,"tag":558,"props":925,"children":926},{"style":670},[927],{"type":419,"value":683},{"type":414,"tag":558,"props":929,"children":930},{"style":565},[931],{"type":419,"value":932},"silent ",{"type":414,"tag":558,"props":934,"children":935},{"style":670},[936],{"type":419,"value":683},{"type":414,"tag":558,"props":938,"children":939},{"style":565},[940],{"type":419,"value":941},"override ",{"type":414,"tag":558,"props":943,"children":944},{"style":670},[945],{"type":419,"value":693},{"type":414,"tag":558,"props":947,"children":948},{"style":696},[949],{"type":419,"value":950},"--wait --quiet --addProductLang En-us --config .vsconfig",{"type":414,"tag":558,"props":952,"children":953},{"style":670},[954],{"type":419,"value":704},{"type":414,"tag":608,"props":956,"children":957},{"icon":610},[958],{"type":414,"tag":415,"props":959,"children":960},{},[961],{"type":419,"value":962},"I did not know before trying to automate Visual Studio installation that you could specify parameters to its installer on the command line but that's very useful.",{"type":414,"tag":415,"props":964,"children":965},{},[966],{"type":419,"value":967},"I don't export Visual Studio settings or extensions as most of them can be synchronized through the personalization account (you just have to sign in to Visual Studio with the same account).",{"type":414,"tag":415,"props":969,"children":970},{},[971,973,980],{"type":419,"value":972},"In a similar way, I use ",{"type":414,"tag":460,"props":974,"children":977},{"href":975,"rel":976},"https://code.visualstudio.com/docs/editor/settings-sync",[464],[978],{"type":419,"value":979},"vscode built-in settings synchronization",{"type":419,"value":981}," to share my setup (extensions, settings, keybindings) across machines so I don't have to do a custom installation.",{"type":414,"tag":415,"props":983,"children":984},{},[985,987,994],{"type":419,"value":986},"There is a Rider package available on chocolatey but it is not always up-to-date and I prefer to use the JetBrains ToolBox application to manage the installation and update of my JetBrains tools. Unfortunately, JetBrains ToolBox does not currently have a CLI to automate the installation of Rider and other useful .NET tools (there is an ",{"type":414,"tag":460,"props":988,"children":991},{"href":989,"rel":990},"https://youtrack.jetbrains.com/issue/TBX-653/toolbox-cli",[464],[992],{"type":419,"value":993},"issue",{"type":419,"value":995}," opened though if you want to vote) so I only automated the installation of JetBrains ToolBox and will have to install it Rider manually from it.",{"type":414,"tag":791,"props":997,"children":999},{"id":998},"tools-i-need",[1000],{"type":419,"value":1001},"Tools I need",{"type":414,"tag":415,"props":1003,"children":1004},{},[1005,1007,1014,1016,1022],{"type":419,"value":1006},"Of course, git is a must-have. I use ",{"type":414,"tag":460,"props":1008,"children":1011},{"href":1009,"rel":1010},"https://github.com/coreybutler/nvm-windows",[464],[1012],{"type":419,"value":1013},"NVM for windows",{"type":419,"value":1015}," to manage multiple installations of node.js on my laptop, and ",{"type":414,"tag":460,"props":1017,"children":1020},{"href":1018,"rel":1019},"https://pnpm.io/",[464],[1021],{"type":419,"value":362},{"type":419,"value":1023}," is my preferred package manager for Node.js.",{"type":414,"tag":415,"props":1025,"children":1026},{},[1027,1029,1035,1036,1043,1045,1052,1054,1060],{"type":419,"value":1028},"There are 2 shells I like to use (both of them are cross-platform): ",{"type":414,"tag":460,"props":1030,"children":1033},{"href":1031,"rel":1032},"https://docs.microsoft.com/en-us/powershell/scripting/overview",[464],[1034],{"type":419,"value":249},{"type":419,"value":810},{"type":414,"tag":460,"props":1037,"children":1040},{"href":1038,"rel":1039},"https://www.nushell.sh/",[464],[1041],{"type":419,"value":1042},"Nushell",{"type":419,"value":1044},". I use ",{"type":414,"tag":460,"props":1046,"children":1049},{"href":1047,"rel":1048},"https://ohmyposh.dev/",[464],[1050],{"type":419,"value":1051},"Oh My Posh",{"type":419,"value":1053}," to configure an enhanced prompt for both shells. ",{"type":414,"tag":460,"props":1055,"children":1058},{"href":1056,"rel":1057},"https://docs.microsoft.com/en-us/windows/terminal/",[464],[1059],{"type":419,"value":275},{"type":419,"value":1061}," is my go-to terminal.",{"type":414,"tag":415,"props":1063,"children":1064},{},[1065],{"type":419,"value":1066},"As I work mainly on cloud projects, there are some Azure tools I need on my laptop:",{"type":414,"tag":548,"props":1068,"children":1070},{"className":644,"code":1069,"language":248,"meta":401,"style":401},"winget install -e -h --id Microsoft.AzureCLI\nwinget install -e -h --id Microsoft.AzureCosmosEmulator\nwinget install -e -h --id Microsoft.AzureDataStudio\nwinget install -e -h --id Microsoft.azure-iot-explorer\nwinget install -e -h --id Microsoft.AzureStorageExplorer\nwinget install -e -h --id Pulumi.Pulumi\nwinget install -e -h --id Microsoft.AzureFunctionsCoreTools\n# Azurite can be installed through vscode extension or as a global npm package\n# pnpm add -g azurite\n",[1071],{"type":414,"tag":554,"props":1072,"children":1073},{"__ignoreMap":401},[1074,1106,1138,1170,1220,1253,1286,1319,1328],{"type":414,"tag":558,"props":1075,"children":1076},{"class":560,"line":561},[1077,1081,1085,1089,1093,1097,1101],{"type":414,"tag":558,"props":1078,"children":1079},{"style":565},[1080],{"type":419,"value":885},{"type":414,"tag":558,"props":1082,"children":1083},{"style":670},[1084],{"type":419,"value":673},{"type":414,"tag":558,"props":1086,"children":1087},{"style":565},[1088],{"type":419,"value":894},{"type":414,"tag":558,"props":1090,"children":1091},{"style":670},[1092],{"type":419,"value":673},{"type":414,"tag":558,"props":1094,"children":1095},{"style":565},[1096],{"type":419,"value":903},{"type":414,"tag":558,"props":1098,"children":1099},{"style":670},[1100],{"type":419,"value":683},{"type":414,"tag":558,"props":1102,"children":1103},{"style":565},[1104],{"type":419,"value":1105},"id Microsoft.AzureCLI\n",{"type":414,"tag":558,"props":1107,"children":1108},{"class":560,"line":661},[1109,1113,1117,1121,1125,1129,1133],{"type":414,"tag":558,"props":1110,"children":1111},{"style":565},[1112],{"type":419,"value":885},{"type":414,"tag":558,"props":1114,"children":1115},{"style":670},[1116],{"type":419,"value":673},{"type":414,"tag":558,"props":1118,"children":1119},{"style":565},[1120],{"type":419,"value":894},{"type":414,"tag":558,"props":1122,"children":1123},{"style":670},[1124],{"type":419,"value":673},{"type":414,"tag":558,"props":1126,"children":1127},{"style":565},[1128],{"type":419,"value":903},{"type":414,"tag":558,"props":1130,"children":1131},{"style":670},[1132],{"type":419,"value":683},{"type":414,"tag":558,"props":1134,"children":1135},{"style":565},[1136],{"type":419,"value":1137},"id Microsoft.AzureCosmosEmulator\n",{"type":414,"tag":558,"props":1139,"children":1140},{"class":560,"line":707},[1141,1145,1149,1153,1157,1161,1165],{"type":414,"tag":558,"props":1142,"children":1143},{"style":565},[1144],{"type":419,"value":885},{"type":414,"tag":558,"props":1146,"children":1147},{"style":670},[1148],{"type":419,"value":673},{"type":414,"tag":558,"props":1150,"children":1151},{"style":565},[1152],{"type":419,"value":894},{"type":414,"tag":558,"props":1154,"children":1155},{"style":670},[1156],{"type":419,"value":673},{"type":414,"tag":558,"props":1158,"children":1159},{"style":565},[1160],{"type":419,"value":903},{"type":414,"tag":558,"props":1162,"children":1163},{"style":670},[1164],{"type":419,"value":683},{"type":414,"tag":558,"props":1166,"children":1167},{"style":565},[1168],{"type":419,"value":1169},"id Microsoft.AzureDataStudio\n",{"type":414,"tag":558,"props":1171,"children":1172},{"class":560,"line":716},[1173,1177,1181,1185,1189,1193,1197,1202,1206,1211,1215],{"type":414,"tag":558,"props":1174,"children":1175},{"style":565},[1176],{"type":419,"value":885},{"type":414,"tag":558,"props":1178,"children":1179},{"style":670},[1180],{"type":419,"value":673},{"type":414,"tag":558,"props":1182,"children":1183},{"style":565},[1184],{"type":419,"value":894},{"type":414,"tag":558,"props":1186,"children":1187},{"style":670},[1188],{"type":419,"value":673},{"type":414,"tag":558,"props":1190,"children":1191},{"style":565},[1192],{"type":419,"value":903},{"type":414,"tag":558,"props":1194,"children":1195},{"style":670},[1196],{"type":419,"value":683},{"type":414,"tag":558,"props":1198,"children":1199},{"style":565},[1200],{"type":419,"value":1201},"id Microsoft.azure",{"type":414,"tag":558,"props":1203,"children":1204},{"style":670},[1205],{"type":419,"value":673},{"type":414,"tag":558,"props":1207,"children":1208},{"style":565},[1209],{"type":419,"value":1210},"iot",{"type":414,"tag":558,"props":1212,"children":1213},{"style":670},[1214],{"type":419,"value":673},{"type":414,"tag":558,"props":1216,"children":1217},{"style":565},[1218],{"type":419,"value":1219},"explorer\n",{"type":414,"tag":558,"props":1221,"children":1223},{"class":560,"line":1222},5,[1224,1228,1232,1236,1240,1244,1248],{"type":414,"tag":558,"props":1225,"children":1226},{"style":565},[1227],{"type":419,"value":885},{"type":414,"tag":558,"props":1229,"children":1230},{"style":670},[1231],{"type":419,"value":673},{"type":414,"tag":558,"props":1233,"children":1234},{"style":565},[1235],{"type":419,"value":894},{"type":414,"tag":558,"props":1237,"children":1238},{"style":670},[1239],{"type":419,"value":673},{"type":414,"tag":558,"props":1241,"children":1242},{"style":565},[1243],{"type":419,"value":903},{"type":414,"tag":558,"props":1245,"children":1246},{"style":670},[1247],{"type":419,"value":683},{"type":414,"tag":558,"props":1249,"children":1250},{"style":565},[1251],{"type":419,"value":1252},"id Microsoft.AzureStorageExplorer\n",{"type":414,"tag":558,"props":1254,"children":1256},{"class":560,"line":1255},6,[1257,1261,1265,1269,1273,1277,1281],{"type":414,"tag":558,"props":1258,"children":1259},{"style":565},[1260],{"type":419,"value":885},{"type":414,"tag":558,"props":1262,"children":1263},{"style":670},[1264],{"type":419,"value":673},{"type":414,"tag":558,"props":1266,"children":1267},{"style":565},[1268],{"type":419,"value":894},{"type":414,"tag":558,"props":1270,"children":1271},{"style":670},[1272],{"type":419,"value":673},{"type":414,"tag":558,"props":1274,"children":1275},{"style":565},[1276],{"type":419,"value":903},{"type":414,"tag":558,"props":1278,"children":1279},{"style":670},[1280],{"type":419,"value":683},{"type":414,"tag":558,"props":1282,"children":1283},{"style":565},[1284],{"type":419,"value":1285},"id Pulumi.Pulumi\n",{"type":414,"tag":558,"props":1287,"children":1289},{"class":560,"line":1288},7,[1290,1294,1298,1302,1306,1310,1314],{"type":414,"tag":558,"props":1291,"children":1292},{"style":565},[1293],{"type":419,"value":885},{"type":414,"tag":558,"props":1295,"children":1296},{"style":670},[1297],{"type":419,"value":673},{"type":414,"tag":558,"props":1299,"children":1300},{"style":565},[1301],{"type":419,"value":894},{"type":414,"tag":558,"props":1303,"children":1304},{"style":670},[1305],{"type":419,"value":673},{"type":414,"tag":558,"props":1307,"children":1308},{"style":565},[1309],{"type":419,"value":903},{"type":414,"tag":558,"props":1311,"children":1312},{"style":670},[1313],{"type":419,"value":683},{"type":414,"tag":558,"props":1315,"children":1316},{"style":565},[1317],{"type":419,"value":1318},"id Microsoft.AzureFunctionsCoreTools\n",{"type":414,"tag":558,"props":1320,"children":1322},{"class":560,"line":1321},8,[1323],{"type":414,"tag":558,"props":1324,"children":1325},{"style":655},[1326],{"type":419,"value":1327},"# Azurite can be installed through vscode extension or as a global npm package\n",{"type":414,"tag":558,"props":1329,"children":1331},{"class":560,"line":1330},9,[1332],{"type":414,"tag":558,"props":1333,"children":1334},{"style":655},[1335],{"type":419,"value":1336},"# pnpm add -g azurite\n",{"type":414,"tag":415,"props":1338,"children":1339},{},[1340,1342,1349,1351,1358],{"type":419,"value":1341},"My script also automates the installation of other tools, not related to software development but that I often use (like ",{"type":414,"tag":460,"props":1343,"children":1346},{"href":1344,"rel":1345},"https://www.7-zip.org/",[464],[1347],{"type":419,"value":1348},"7zip",{"type":419,"value":1350},", ",{"type":414,"tag":460,"props":1352,"children":1355},{"href":1353,"rel":1354},"https://docs.microsoft.com/en-us/windows/powertoys/",[464],[1356],{"type":419,"value":1357},"Microsoft Power Toys",{"type":419,"value":1359}," or just browsers).",{"type":414,"tag":415,"props":1361,"children":1362},{},[1363],{"type":419,"value":1364},"Generally, when the applications I want to install are available in the Microsoft Store, I specify winget to install them from there.",{"type":414,"tag":548,"props":1366,"children":1368},{"className":644,"code":1367,"language":248,"meta":401,"style":401},"winget install -e -h --id Microsoft.WindowsTerminal -s msstore\n",[1369],{"type":414,"tag":554,"props":1370,"children":1371},{"__ignoreMap":401},[1372],{"type":414,"tag":558,"props":1373,"children":1374},{"class":560,"line":561},[1375,1379,1383,1387,1391,1395,1399,1404,1408],{"type":414,"tag":558,"props":1376,"children":1377},{"style":565},[1378],{"type":419,"value":885},{"type":414,"tag":558,"props":1380,"children":1381},{"style":670},[1382],{"type":419,"value":673},{"type":414,"tag":558,"props":1384,"children":1385},{"style":565},[1386],{"type":419,"value":894},{"type":414,"tag":558,"props":1388,"children":1389},{"style":670},[1390],{"type":419,"value":673},{"type":414,"tag":558,"props":1392,"children":1393},{"style":565},[1394],{"type":419,"value":903},{"type":414,"tag":558,"props":1396,"children":1397},{"style":670},[1398],{"type":419,"value":683},{"type":414,"tag":558,"props":1400,"children":1401},{"style":565},[1402],{"type":419,"value":1403},"id Microsoft.WindowsTerminal ",{"type":414,"tag":558,"props":1405,"children":1406},{"style":670},[1407],{"type":419,"value":673},{"type":414,"tag":558,"props":1409,"children":1410},{"style":565},[1411],{"type":419,"value":1412},"s msstore\n",{"type":414,"tag":608,"props":1414,"children":1415},{"icon":610},[1416],{"type":414,"tag":415,"props":1417,"children":1418},{},[1419],{"type":419,"value":1420},"Automating the installation of my developer machine was the opportunity to realize all the tools I was using daily, and which ones were really useful.",{"type":414,"tag":791,"props":1422,"children":1424},{"id":1423},"tools-i-dont-need",[1425],{"type":419,"value":1426},"Tools I don't need",{"type":414,"tag":415,"props":1428,"children":1429},{},[1430],{"type":419,"value":1431},"Unnecessary applications that come with Windows out of the box are uninstalled using this function:",{"type":414,"tag":548,"props":1433,"children":1435},{"className":644,"code":1434,"language":248,"meta":401,"style":401},"function removeApp {\n    Param ([string]$appName)\n    Write-Output \"Trying to remove $appName\"\n    Get-AppxPackage $appName -AllUsers | Remove-AppxPackage\n    Get-AppXProvisionedPackage -Online | Where DisplayName -like $appName | Remove-AppxProvisionedPackage -Online\n",[1436],{"type":414,"tag":554,"props":1437,"children":1438},{"__ignoreMap":401},[1439,1458,1492,1523,1560],{"type":414,"tag":558,"props":1440,"children":1441},{"class":560,"line":561},[1442,1448,1453],{"type":414,"tag":558,"props":1443,"children":1445},{"style":1444},"--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA",[1446],{"type":419,"value":1447},"function",{"type":414,"tag":558,"props":1449,"children":1450},{"style":730},[1451],{"type":419,"value":1452}," removeApp",{"type":414,"tag":558,"props":1454,"children":1455},{"style":670},[1456],{"type":419,"value":1457}," {\n",{"type":414,"tag":558,"props":1459,"children":1460},{"class":560,"line":661},[1461,1467,1472,1477,1482,1487],{"type":414,"tag":558,"props":1462,"children":1464},{"style":1463},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF;--shiki-light-font-style:italic;--shiki-default-font-style:italic;--shiki-dark-font-style:italic",[1465],{"type":419,"value":1466},"    Param",{"type":414,"tag":558,"props":1468,"children":1469},{"style":670},[1470],{"type":419,"value":1471}," ([",{"type":414,"tag":558,"props":1473,"children":1474},{"style":1444},[1475],{"type":419,"value":1476},"string",{"type":414,"tag":558,"props":1478,"children":1479},{"style":670},[1480],{"type":419,"value":1481},"]$",{"type":414,"tag":558,"props":1483,"children":1484},{"style":565},[1485],{"type":419,"value":1486},"appName",{"type":414,"tag":558,"props":1488,"children":1489},{"style":670},[1490],{"type":419,"value":1491},")\n",{"type":414,"tag":558,"props":1493,"children":1494},{"class":560,"line":707},[1495,1500,1505,1510,1515,1519],{"type":414,"tag":558,"props":1496,"children":1497},{"style":730},[1498],{"type":419,"value":1499},"    Write-Output",{"type":414,"tag":558,"props":1501,"children":1502},{"style":670},[1503],{"type":419,"value":1504}," \"",{"type":414,"tag":558,"props":1506,"children":1507},{"style":696},[1508],{"type":419,"value":1509},"Trying to remove ",{"type":414,"tag":558,"props":1511,"children":1512},{"style":670},[1513],{"type":419,"value":1514},"$",{"type":414,"tag":558,"props":1516,"children":1517},{"style":565},[1518],{"type":419,"value":1486},{"type":414,"tag":558,"props":1520,"children":1521},{"style":670},[1522],{"type":419,"value":704},{"type":414,"tag":558,"props":1524,"children":1525},{"class":560,"line":716},[1526,1531,1536,1541,1545,1550,1555],{"type":414,"tag":558,"props":1527,"children":1528},{"style":730},[1529],{"type":419,"value":1530},"    Get-AppxPackage",{"type":414,"tag":558,"props":1532,"children":1533},{"style":670},[1534],{"type":419,"value":1535}," $",{"type":414,"tag":558,"props":1537,"children":1538},{"style":565},[1539],{"type":419,"value":1540},"appName ",{"type":414,"tag":558,"props":1542,"children":1543},{"style":670},[1544],{"type":419,"value":673},{"type":414,"tag":558,"props":1546,"children":1547},{"style":565},[1548],{"type":419,"value":1549},"AllUsers ",{"type":414,"tag":558,"props":1551,"children":1552},{"style":670},[1553],{"type":419,"value":1554},"|",{"type":414,"tag":558,"props":1556,"children":1557},{"style":730},[1558],{"type":419,"value":1559}," Remove-AppxPackage\n",{"type":414,"tag":558,"props":1561,"children":1562},{"class":560,"line":1222},[1563,1568,1573,1578,1582,1587,1592,1597,1601,1605,1609,1614,1618],{"type":414,"tag":558,"props":1564,"children":1565},{"style":730},[1566],{"type":419,"value":1567},"    Get-AppXProvisionedPackage",{"type":414,"tag":558,"props":1569,"children":1570},{"style":670},[1571],{"type":419,"value":1572}," -",{"type":414,"tag":558,"props":1574,"children":1575},{"style":565},[1576],{"type":419,"value":1577},"Online ",{"type":414,"tag":558,"props":1579,"children":1580},{"style":670},[1581],{"type":419,"value":1554},{"type":414,"tag":558,"props":1583,"children":1584},{"style":1463},[1585],{"type":419,"value":1586}," Where",{"type":414,"tag":558,"props":1588,"children":1589},{"style":565},[1590],{"type":419,"value":1591}," DisplayName ",{"type":414,"tag":558,"props":1593,"children":1594},{"style":670},[1595],{"type":419,"value":1596},"-like",{"type":414,"tag":558,"props":1598,"children":1599},{"style":670},[1600],{"type":419,"value":1535},{"type":414,"tag":558,"props":1602,"children":1603},{"style":565},[1604],{"type":419,"value":1540},{"type":414,"tag":558,"props":1606,"children":1607},{"style":670},[1608],{"type":419,"value":1554},{"type":414,"tag":558,"props":1610,"children":1611},{"style":730},[1612],{"type":419,"value":1613}," Remove-AppxProvisionedPackage",{"type":414,"tag":558,"props":1615,"children":1616},{"style":670},[1617],{"type":419,"value":1572},{"type":414,"tag":558,"props":1619,"children":1620},{"style":565},[1621],{"type":419,"value":1622},"Online\n",{"type":414,"tag":415,"props":1624,"children":1625},{},[1626,1628,1634,1636,1642],{"type":419,"value":1627},"It allows me to get rid of pre-installed applications like ",{"type":414,"tag":554,"props":1629,"children":1631},{"className":1630},[],[1632],{"type":419,"value":1633},"Facebook",{"type":419,"value":1635},"or ",{"type":414,"tag":554,"props":1637,"children":1639},{"className":1638},[],[1640],{"type":419,"value":1641},"Bing News",{"type":419,"value":597},{"type":414,"tag":421,"props":1644,"children":1646},{"id":1645},"configuring-software",[1647],{"type":419,"value":1648},"Configuring software",{"type":414,"tag":415,"props":1650,"children":1651},{},[1652],{"type":419,"value":1653},"Installing software is one part, but configuring it is another. As I previously mentioned, for some applications in which you sign in with an account, settings are synchronized so you don't need to transfer the application settings from your previous laptop. For the others, I decided to use symbolic links.",{"type":414,"tag":415,"props":1655,"children":1656},{},[1657],{"type":414,"tag":441,"props":1658,"children":1662},{"alt":1659,"className":1660,"src":1661},"A light bulb that is turned on.",[445,446],"/posts/images/automate_developer_machine_idea.jpg",[],{"type":414,"tag":415,"props":1664,"children":1665},{},[1666],{"type":419,"value":1667},"Here are some examples of settings I wanted to set up on a new laptop:",{"type":414,"tag":491,"props":1669,"children":1670},{},[1671,1683,1694,1705],{"type":414,"tag":495,"props":1672,"children":1673},{},[1674,1676],{"type":419,"value":1675},"my ",{"type":414,"tag":460,"props":1677,"children":1680},{"href":1678,"rel":1679},"https://github.com/TechWatching/dotfiles/blob/main/config/git/.gitconfig",[464],[1681],{"type":419,"value":1682},".gitconfig file",{"type":414,"tag":495,"props":1684,"children":1685},{},[1686,1687],{"type":419,"value":1675},{"type":414,"tag":460,"props":1688,"children":1691},{"href":1689,"rel":1690},"https://github.com/TechWatching/dotfiles/blob/main/config/windowsTerminal/settings.json",[464],[1692],{"type":419,"value":1693},"Windows Terminal settings",{"type":414,"tag":495,"props":1695,"children":1696},{},[1697,1698],{"type":419,"value":1675},{"type":414,"tag":460,"props":1699,"children":1702},{"href":1700,"rel":1701},"https://github.com/TechWatching/dotfiles/blob/main/config/powershell/Microsoft.PowerShell_profile.ps1",[464],[1703],{"type":419,"value":1704},"PowerShell profile",{"type":414,"tag":495,"props":1706,"children":1707},{},[1708,1709,1716],{"type":419,"value":1675},{"type":414,"tag":460,"props":1710,"children":1713},{"href":1711,"rel":1712},"https://github.com/TechWatching/dotfiles/blob/main/config/prompt/.oh-my-posh.omp.json",[464],[1714],{"type":419,"value":1715},"custom prompt configuration",{"type":419,"value":1717}," done using oh my posh",{"type":414,"tag":415,"props":1719,"children":1720},{},[1721,1723,1728],{"type":419,"value":1722},"To create a symbolic link at the Windows Terminal settings file pointing to the settings file in my ",{"type":414,"tag":554,"props":1724,"children":1726},{"className":1725},[],[1727],{"type":419,"value":595},{"type":419,"value":1729}," cloned repository I can do the following command:",{"type":414,"tag":548,"props":1731,"children":1733},{"className":644,"code":1732,"language":248,"meta":401,"style":401},"New-Item -ItemType SymbolicLink -Path \"$env:USERPROFILE\\AppData\\Local\\Packages\\Microsoft.WindowsTerminal_8wekyb3d8bbwe\\LocalState\\settings.json\" -Target \"$env:USERPROFILE\\dotfiles\\config\\windowsTerminal\\settings.json\"\"\n",[1734],{"type":414,"tag":554,"props":1735,"children":1736},{"__ignoreMap":401},[1737],{"type":414,"tag":558,"props":1738,"children":1739},{"class":560,"line":561},[1740,1745,1749,1754,1758,1763,1767,1771,1776,1780,1784,1789,1793,1797,1802],{"type":414,"tag":558,"props":1741,"children":1742},{"style":730},[1743],{"type":419,"value":1744},"New-Item",{"type":414,"tag":558,"props":1746,"children":1747},{"style":670},[1748],{"type":419,"value":1572},{"type":414,"tag":558,"props":1750,"children":1751},{"style":565},[1752],{"type":419,"value":1753},"ItemType SymbolicLink ",{"type":414,"tag":558,"props":1755,"children":1756},{"style":670},[1757],{"type":419,"value":673},{"type":414,"tag":558,"props":1759,"children":1760},{"style":565},[1761],{"type":419,"value":1762},"Path ",{"type":414,"tag":558,"props":1764,"children":1765},{"style":670},[1766],{"type":419,"value":757},{"type":414,"tag":558,"props":1768,"children":1769},{"style":565},[1770],{"type":419,"value":762},{"type":414,"tag":558,"props":1772,"children":1773},{"style":696},[1774],{"type":419,"value":1775},"\\AppData\\Local\\Packages\\Microsoft.WindowsTerminal_8wekyb3d8bbwe\\LocalState\\settings.json",{"type":414,"tag":558,"props":1777,"children":1778},{"style":670},[1779],{"type":419,"value":693},{"type":414,"tag":558,"props":1781,"children":1782},{"style":670},[1783],{"type":419,"value":1572},{"type":414,"tag":558,"props":1785,"children":1786},{"style":565},[1787],{"type":419,"value":1788},"Target ",{"type":414,"tag":558,"props":1790,"children":1791},{"style":670},[1792],{"type":419,"value":757},{"type":414,"tag":558,"props":1794,"children":1795},{"style":565},[1796],{"type":419,"value":762},{"type":414,"tag":558,"props":1798,"children":1799},{"style":696},[1800],{"type":419,"value":1801},"\\dotfiles\\config\\windowsTerminal\\settings.json",{"type":414,"tag":558,"props":1803,"children":1804},{"style":565},[1805],{"type":419,"value":1806},"\"\"\n",{"type":414,"tag":415,"props":1808,"children":1809},{},[1810],{"type":419,"value":1811},"Because I use symbolic links, when I modify the configuration of my Windows Terminal (event through the UI), the settings file in my git repository is the one being modified so I can commit it and push it so that my other machines have the latest version. And it's the same for all my settings files.",{"type":414,"tag":415,"props":1813,"children":1814},{},[1815],{"type":419,"value":1816},"There are others settings in my repository and I will probably continue to add some later.",{"type":414,"tag":421,"props":1818,"children":1820},{"id":1819},"what-i-did-not-automate-yet",[1821],{"type":419,"value":1822},"What I did not automate ... yet!",{"type":414,"tag":415,"props":1824,"children":1825},{},[1826],{"type":419,"value":1827},"There are many things I did not automate yet and that I will do bit by bit.  Nevertheless, I am happy with the current setup. There is much room for improvement but I've already won some time last time I changed my laptop, and that was the goal.",{"type":414,"tag":415,"props":1829,"children":1830},{},[1831,1833,1840,1842,1848],{"type":419,"value":1832},"As I've just said, there are other configurations I would probably need to store in my repository. ",{"type":414,"tag":460,"props":1834,"children":1837},{"href":1835,"rel":1836},"https://docs.microsoft.com/en-us/windows/powertoys",[464],[1838],{"type":419,"value":1839},"Power Toys",{"type":419,"value":1841}," settings might be one of them unless they add a settings sync (issue already opened ",{"type":414,"tag":460,"props":1843,"children":1846},{"href":1844,"rel":1845},"https://github.com/microsoft/PowerToys/issues/3381",[464],[1847],{"type":419,"value":838},{"type":419,"value":1849},"). It would be better because there are many settings files so only using symbolic links could be cumbersome.",{"type":414,"tag":415,"props":1851,"children":1852},{},[1853,1855,1862],{"type":419,"value":1854},"Most of the software I need is installed by my setup script. One exception is JetBrains products but I hope it will be possible soon. I have some commented lines in my installation script about automating the setup of ",{"type":414,"tag":460,"props":1856,"children":1859},{"href":1857,"rel":1858},"https://docs.microsoft.com/en-us/windows/wsl/install",[464],[1860],{"type":419,"value":1861},"WSL2",{"type":419,"value":1863}," and docker (well installation of Rancher Desktop to be more precise as a replacement of Docker Desktop due to its new license model) that required some windows features to be installed.  I think these lines should work with some adjustments, it's just that I did that manually last time and did not take the time to test the corresponding commands properly.",{"type":414,"tag":415,"props":1865,"children":1866},{},[1867],{"type":419,"value":1868},"There are also some limitations to my current approach to installing my developer machine:",{"type":414,"tag":491,"props":1870,"children":1871},{},[1872,1886,1891],{"type":414,"tag":495,"props":1873,"children":1874},{},[1875,1877,1884],{"type":419,"value":1876},"As everything is contained in a public GitHub repository, I can't keep some files or secrets private obviously (it could be useful to configure a new machine to ",{"type":414,"tag":460,"props":1878,"children":1881},{"href":1879,"rel":1880},"https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits",[464],[1882],{"type":419,"value":1883},"sign commits",{"type":419,"value":1885}," for instance)",{"type":414,"tag":495,"props":1887,"children":1888},{},[1889],{"type":419,"value":1890},"The installation script is not idempotent so it will try to re-install and re-configure everything if I re-run it (not a big deal as I mainly use it to install a new machine, but it would be nice to be able to just re-run it to get on an existing installation all the latest improvements I made on another laptop)",{"type":414,"tag":495,"props":1892,"children":1893},{},[1894],{"type":419,"value":1895},"I did not set up anything to handle multiple configurations (one for my personal laptop and one for my professional laptop for example)",{"type":414,"tag":415,"props":1897,"children":1898},{},[1899,1901,1908],{"type":419,"value":1900},"I think the tool ",{"type":414,"tag":460,"props":1902,"children":1905},{"href":1903,"rel":1904},"https://www.chezmoi.io/",[464],[1906],{"type":419,"value":1907},"chezmoi",{"type":419,"value":1909}," might help to solve some of these limitations. Maybe one day I'll take the time to dig a little deeper to see if I can improve the whole process.",{"type":414,"tag":421,"props":1911,"children":1913},{"id":1912},"to-conclude",[1914],{"type":419,"value":1915},"To conclude",{"type":414,"tag":415,"props":1917,"children":1918},{},[1919,1921,1927],{"type":419,"value":1920},"You can find the repository with all the code I use to automate my installation ",{"type":414,"tag":460,"props":1922,"children":1925},{"href":1923,"rel":1924},"https://github.com/TechWatching/dotfiles",[464],[1926],{"type":419,"value":838},{"type":419,"value":597},{"type":414,"tag":415,"props":1929,"children":1930},{},[1931],{"type":419,"value":1932},"Automating my machine installation was not that fun, but I learned lots of things while doing it about package managers, windows, symbolic links, PowerShell... And in the end, it is very satisfying when everything starts to install automatically and you find a familiar environment on a new laptop.",{"type":414,"tag":415,"props":1934,"children":1935},{},[1936],{"type":419,"value":1937},"Whether you adopt this approach or another to automate the setup of your development machine, I think it's an important thing to do. It does not have to be complex, and you don't need to automate everything. But you should probably at least use a package manager for your software installations, have a list somewhere of the most useful tools you need, and keep a copy of the configuration files of your most important tools.",{"type":414,"tag":415,"props":1939,"children":1940},{},[1941,1943,1950],{"type":419,"value":1942},"This article is part of the ",{"type":414,"tag":460,"props":1944,"children":1947},{"href":1945,"rel":1946},"https://townhall.hashnode.com/4-articles-in-4-weeks-hashnode-writing-contest",[464],[1948],{"type":419,"value":1949},"4 articles in 4 weeks Hashnode writing contest",{"type":419,"value":597},{"type":414,"tag":415,"props":1952,"children":1953},{},[1954],{"type":419,"value":1955},"Happy learning.",{"type":414,"tag":1957,"props":1958,"children":1959},"style",{},[1960],{"type":419,"value":1961},"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":401,"searchDepth":661,"depth":661,"links":1963},[1964,1965,1966,1972,1973,1974],{"id":423,"depth":661,"text":426},{"id":481,"depth":661,"text":484},{"id":786,"depth":661,"text":789,"children":1967},[1968,1969,1970,1971],{"id":793,"depth":707,"text":796},{"id":843,"depth":707,"text":846},{"id":998,"depth":707,"text":1001},{"id":1423,"depth":707,"text":1426},{"id":1645,"depth":661,"text":1648},{"id":1819,"depth":661,"text":1822},{"id":1912,"depth":661,"text":1915},"markdown","content:1.posts:42.automate-developer-machine.md","content","1.posts/42.automate-developer-machine.md","md",{"_path":73,"_dir":399,"_draft":400,"_partial":400,"_locale":401,"title":72,"description":1981,"date":1982,"image":1983,"badge":1985,"tags":1987,"body":1988,"_type":1975,"_id":2614,"_source":1977,"_file":2615,"_extension":1979},"I recently played a bit with GitHub Actions and as I have spent some time running, again and again, my workflows to understand what was going wrong I thought it could be interesting to share what I have learned especially concerning environment variables and contexts.","2021-09-06T00:00:00.000Z",{"src":1984},"/images/github-figurine_1.jpg",{"label":1986},"Tips",[249,307,309],{"type":411,"children":1989,"toc":2607},[1990,1994,2002,2008,2021,2026,2035,2060,2073,2087,2098,2113,2127,2136,2148,2162,2168,2173,2185,2199,2213,2242,2255,2267,2279,2287,2380,2388,2532,2553,2559,2564,2585,2594,2598,2603],{"type":414,"tag":415,"props":1991,"children":1992},{},[1993],{"type":419,"value":1981},{"type":414,"tag":608,"props":1995,"children":1996},{"icon":610},[1997],{"type":414,"tag":415,"props":1998,"children":1999},{},[2000],{"type":419,"value":2001},"Disclaimer: Although I have some experience with Azure Pipelines, I am still learning GitHub Actions so I do not pretend to know everything about them nor do I never make mistakes when writing about them. Feel free to correct me in the comments if you think I am wrong about something or if something that I show can be done more effectively.",{"type":414,"tag":421,"props":2003,"children":2005},{"id":2004},"tip-n1-environment-variables-syntax-depends-on-the-shell-you-are-using-in-your-job",[2006],{"type":419,"value":2007},"Tip n°1: Environment variables syntax depends on the shell you are using in your job",{"type":414,"tag":415,"props":2009,"children":2010},{},[2011,2013,2019],{"type":419,"value":2012},"As you know a GitHub Actions workflow is composed of different jobs where each job is a set of steps that execute on the same runner. As a runner can be hosted Ubuntu, Windows, macOS, or even another operating system (if you host your own runner) the shell that will execute your commands will not be the same by default depending on the runner you choose. For instance, if you are on a Ubuntu GitHub-hosted runner, by default the shell will be bash whereas on a Windows GitHub-hosted runner it will be PowerShell (I think we don't say PowerShell Core anymore but I am speaking of ",{"type":414,"tag":554,"props":2014,"children":2016},{"className":2015},[],[2017],{"type":419,"value":2018},"pwsh",{"type":419,"value":2020},", not the old Windows PowerShell of course).",{"type":414,"tag":415,"props":2022,"children":2023},{},[2024],{"type":419,"value":2025},"This is really important to know because depending on the shell used, the syntax to use an environment variable in a script is different as you can see on the documentation screenshot below:",{"type":414,"tag":415,"props":2027,"children":2028},{},[2029],{"type":414,"tag":441,"props":2030,"children":2034},{"alt":2031,"className":2032,"src":2033},"GitHub Actions' documentation of running a script.",[445,446],"/posts/images/githubactions_envvar_1.png",[],{"type":414,"tag":608,"props":2036,"children":2037},{"icon":610},[2038],{"type":414,"tag":415,"props":2039,"children":2040},{},[2041,2043,2050,2052,2058],{"type":419,"value":2042},"When I am talking about environment variables here I am referring to GitHub ",{"type":414,"tag":460,"props":2044,"children":2047},{"href":2045,"rel":2046},"https://docs.github.com/en/actions/reference/environment-variables",[464],[2048],{"type":419,"value":2049},"default environment variables",{"type":419,"value":2051}," (for instance ",{"type":414,"tag":554,"props":2053,"children":2055},{"className":2054},[],[2056],{"type":419,"value":2057},"GITHUB_EVENT_NAME",{"type":419,"value":2059}," which is the name of the webhook event that triggered the workflow) and to custom variables you set in a workflow. The syntax for environment variables you just create and use in a shell script does not change of course.",{"type":414,"tag":415,"props":2061,"children":2062},{},[2063,2065,2071],{"type":419,"value":2064},"The documentation briefly explains the syntax to use depending on the shell ",{"type":414,"tag":460,"props":2066,"children":2069},{"href":2067,"rel":2068},"https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#using-a-specific-shell",[464],[2070],{"type":419,"value":838},{"type":419,"value":2072}," but you can easily miss it as I did. In fact, most of the GitHub Actions examples you can find are in bash so if you use them as-is without paying attention to the shell you are using, you will probably get it wrong. I lost a lot of time trying to figure out why my scripts were not working on a Windows runner so I hope knowing that you will avoid doing the same.",{"type":414,"tag":421,"props":2074,"children":2076},{"id":2075},"tip-n2-do-not-use-your-repository-github_token-in-tasks-that-need-to-trigger-another-workflow",[2077,2079,2085],{"type":419,"value":2078},"Tip n°2: Do not use your repository ",{"type":414,"tag":554,"props":2080,"children":2082},{"className":2081},[],[2083],{"type":419,"value":2084},"GITHUB_TOKEN",{"type":419,"value":2086}," in tasks that need to trigger another workflow.",{"type":414,"tag":415,"props":2088,"children":2089},{},[2090,2091,2096],{"type":419,"value":572},{"type":414,"tag":554,"props":2092,"children":2094},{"className":2093},[],[2095],{"type":419,"value":2084},{"type":419,"value":2097}," is a secret you can use in your workflow to do some actions on your GitHub repository like pushing a tag, creating a new release, creating an issue... It is very convenient because it allows you to automate in your workflow many things for your GitHub repository using built-in actions or the GitHub REST API.",{"type":414,"tag":608,"props":2099,"children":2100},{"icon":610},[2101],{"type":414,"tag":415,"props":2102,"children":2103},{},[2104,2106,2111],{"type":419,"value":2105},"Be aware that internally GitHub Actions is a GitHub App that is installed on your repository when you start creating GitHub Actions workflows for this repository. That means the token represented by ",{"type":414,"tag":554,"props":2107,"children":2109},{"className":2108},[],[2110],{"type":419,"value":2084},{"type":419,"value":2112}," in your workflow is a GitHub App installation token that will only work on your repository workflow and that will have a limited set of permissions (but you can grant more permissions directly in your workflow if you want).",{"type":414,"tag":415,"props":2114,"children":2115},{},[2116,2118,2125],{"type":419,"value":2117},"If you want to know about authentication in a workflow, there is a dedicated ",{"type":414,"tag":460,"props":2119,"children":2122},{"href":2120,"rel":2121},"https://docs.github.com/en/actions/reference/authentication-in-a-workflow",[464],[2123],{"type":419,"value":2124},"page",{"type":419,"value":2126}," on the topic in the GitHub documentation. However, if you read it quickly you may miss an important piece of information:",{"type":414,"tag":2128,"props":2129,"children":2130},"blockquote",{},[2131],{"type":414,"tag":415,"props":2132,"children":2133},{},[2134],{"type":419,"value":2135},"\"events triggered by the GITHUB_TOKEN will not create a new workflow run\"",{"type":414,"tag":415,"props":2137,"children":2138},{},[2139,2141,2146],{"type":419,"value":2140},"What does this mean? It means that if you have 2 workflows and that the first one uses the ",{"type":414,"tag":554,"props":2142,"children":2144},{"className":2143},[],[2145],{"type":419,"value":2084},{"type":419,"value":2147}," for an action that should trigger the second one, then the second workflow will never be triggered. The aim is to prevent you from making an infinite loop of workflows runs triggering each other.",{"type":414,"tag":415,"props":2149,"children":2150},{},[2151,2153,2160],{"type":419,"value":2152},"So imagine you want to implement a workflow that publishes a release when a new tag is pushed on a repository and another workflow that automatically tweets about your new release once it is published, how can you do that? You just have to ",{"type":414,"tag":460,"props":2154,"children":2157},{"href":2155,"rel":2156},"https://docs.github.com/en/github/authenticating-to-github/keeping-your-account-and-data-secure/creating-a-personal-access-token",[464],[2158],{"type":419,"value":2159},"create a GitHub Personal Access Token",{"type":419,"value":2161},", add it as a secret in your repository, and use it in your first workflow to create your release. This way, the second workflow will run fine when the release is published.",{"type":414,"tag":421,"props":2163,"children":2165},{"id":2164},"tip-n3-assign-information-from-the-event-triggering-a-github-actions-workflow-to-a-powershell-variable",[2166],{"type":419,"value":2167},"Tip n°3: Assign information from the event triggering a GitHub Actions workflow to a PowerShell variable.",{"type":414,"tag":415,"props":2169,"children":2170},{},[2171],{"type":419,"value":2172},"Sometimes, in a GitHub Actions workflow, we want to execute some PowerShell to do specific actions depending on information from the event that triggered the workflow. Hence having a PowerShell variable with this data could be useful. For instance, if we have a workflow triggered by the publication of a release, maybe we need to retrieve the URLs of the binaries of this release which can be done easily if the event data is in a PowerShell variable.",{"type":414,"tag":415,"props":2174,"children":2175},{},[2176,2178,2183],{"type":419,"value":2177},"The webhook payload corresponding to the event that triggered a workflow is part of the properties of the ",{"type":414,"tag":554,"props":2179,"children":2181},{"className":2180},[],[2182],{"type":419,"value":232},{"type":419,"value":2184}," context.",{"type":414,"tag":608,"props":2186,"children":2187},{"icon":610},[2188],{"type":414,"tag":415,"props":2189,"children":2190},{},[2191,2193],{"type":419,"value":2192},"If you are not familiar with contexts in GitHub Actions, they are objects that contain information about the current workflow, job, runner, or things like that. Contexts are often used in expressions to determine whether or not a step of the workflow should be executed or to set some variables as you can see in the sample below.\n",{"type":414,"tag":441,"props":2194,"children":2198},{"alt":2195,"className":2196,"src":2197},"GitHub Actions sample to create a draft release.",[445,446],"/posts/images/githubactions_context_1.png",[],{"type":414,"tag":415,"props":2200,"children":2201},{},[2202,2204,2211],{"type":419,"value":2203},"As you can read in the ",{"type":414,"tag":460,"props":2205,"children":2208},{"href":2206,"rel":2207},"https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions",[464],[2209],{"type":419,"value":2210},"documentation",{"type":419,"value":2212},", the event property is of type object which makes it difficult to query it and to assign it to a PowerShell variable. Fortunately, there are ways to do that which are based on the fact that GitHub event data is persisted in a JSON file on the runner file system.",{"type":414,"tag":415,"props":2214,"children":2215},{},[2216,2218,2228,2230,2241],{"type":419,"value":2217},"The first one is to use the tool ",{"type":414,"tag":460,"props":2219,"children":2222},{"href":2220,"rel":2221},"https://stedolan.github.io/jq/",[464],[2223],{"type":414,"tag":554,"props":2224,"children":2226},{"className":2225},[],[2227],{"type":419,"value":309},{"type":419,"value":2229}," which is already installed on GitHub's runners and allows you to process JSON data. Edward Thomson has a blog post that explains how you can use jq with GitHub Actions to do that: ",{"type":414,"tag":460,"props":2231,"children":2234},{"href":2232,"rel":2233},"https://www.edwardthomson.com/blog/github_actions_12_information_about_your_workflow.html",[464],[2235],{"type":414,"tag":554,"props":2236,"children":2238},{"className":2237},[],[2239],{"type":419,"value":2240},"GitHub Actions Day 12: Information about your Workflow",{"type":419,"value":597},{"type":414,"tag":415,"props":2243,"children":2244},{},[2245,2247,2253],{"type":419,"value":2246},"The second one is to directly use PowerShell to grab the GitHub context like this: ",{"type":414,"tag":554,"props":2248,"children":2250},{"className":2249},[],[2251],{"type":419,"value":2252},"$github = Get-Content '${{ github.event_path }}' | ConvertFrom-Json",{"type":419,"value":2254},". Thanks a lot Edward Thomson for helping me with this tip 😀.",{"type":414,"tag":2256,"props":2257,"children":2261},"div",{"className":2258},[2259,2260],"flex","justify-center",[2262],{"type":414,"tag":2263,"props":2264,"children":2266},"tweet",{"id":2265},"1417509550786322440",[],{"type":414,"tag":415,"props":2268,"children":2269},{},[2270,2272,2277],{"type":419,"value":2271},"To illustrate that, here are a sample of using these two ways to assign the URL of the binary published by a release to a PowerShell variable using the event property of the ",{"type":414,"tag":554,"props":2273,"children":2275},{"className":2274},[],[2276],{"type":419,"value":232},{"type":419,"value":2278}," context:",{"type":414,"tag":491,"props":2280,"children":2281},{},[2282],{"type":414,"tag":495,"props":2283,"children":2284},{},[2285],{"type":419,"value":2286},"using jq:",{"type":414,"tag":548,"props":2288,"children":2290},{"className":644,"code":2289,"language":248,"meta":401,"style":401},"$installerUrl = $(jq --raw-output '.release.assets[].browser_download_url | select(contains(\\\"windows.msi\\\"))' \"${{ github.event_path }}\")\n",[2291],{"type":414,"tag":554,"props":2292,"children":2293},{"__ignoreMap":401},[2294],{"type":414,"tag":558,"props":2295,"children":2296},{"class":560,"line":561},[2297,2301,2306,2311,2316,2321,2325,2330,2334,2339,2344,2349,2353,2358,2363,2368,2372,2376],{"type":414,"tag":558,"props":2298,"children":2299},{"style":670},[2300],{"type":419,"value":1514},{"type":414,"tag":558,"props":2302,"children":2303},{"style":565},[2304],{"type":419,"value":2305},"installerUrl ",{"type":414,"tag":558,"props":2307,"children":2308},{"style":670},[2309],{"type":419,"value":2310},"=",{"type":414,"tag":558,"props":2312,"children":2313},{"style":670},[2314],{"type":419,"value":2315}," $(",{"type":414,"tag":558,"props":2317,"children":2318},{"style":565},[2319],{"type":419,"value":2320},"jq ",{"type":414,"tag":558,"props":2322,"children":2323},{"style":670},[2324],{"type":419,"value":683},{"type":414,"tag":558,"props":2326,"children":2327},{"style":565},[2328],{"type":419,"value":2329},"raw",{"type":414,"tag":558,"props":2331,"children":2332},{"style":670},[2333],{"type":419,"value":673},{"type":414,"tag":558,"props":2335,"children":2336},{"style":565},[2337],{"type":419,"value":2338},"output ",{"type":414,"tag":558,"props":2340,"children":2341},{"style":670},[2342],{"type":419,"value":2343},"'",{"type":414,"tag":558,"props":2345,"children":2346},{"style":696},[2347],{"type":419,"value":2348},".release.assets[].browser_download_url | select(contains(\\\"windows.msi\\\"))",{"type":414,"tag":558,"props":2350,"children":2351},{"style":670},[2352],{"type":419,"value":2343},{"type":414,"tag":558,"props":2354,"children":2355},{"style":670},[2356],{"type":419,"value":2357}," \"${",{"type":414,"tag":558,"props":2359,"children":2360},{"style":565},[2361],{"type":419,"value":2362},"{ github.event_path ",{"type":414,"tag":558,"props":2364,"children":2365},{"style":670},[2366],{"type":419,"value":2367},"}",{"type":414,"tag":558,"props":2369,"children":2370},{"style":696},[2371],{"type":419,"value":2367},{"type":414,"tag":558,"props":2373,"children":2374},{"style":670},[2375],{"type":419,"value":693},{"type":414,"tag":558,"props":2377,"children":2378},{"style":670},[2379],{"type":419,"value":1491},{"type":414,"tag":491,"props":2381,"children":2382},{},[2383],{"type":414,"tag":495,"props":2384,"children":2385},{},[2386],{"type":419,"value":2387},"using ConvertFrom-Json method in PowerShell:",{"type":414,"tag":548,"props":2389,"children":2391},{"className":644,"code":2390,"language":248,"meta":401,"style":401},"$github = Get-Content '${{ github.event_path }}' | ConvertFrom-Json\n$installerUrl = $github.release.assets | Where-Object -Property name -match 'windows.msi' | Select -ExpandProperty browser_download_url -First 1\n",[2392],{"type":414,"tag":554,"props":2393,"children":2394},{"__ignoreMap":401},[2395,2440],{"type":414,"tag":558,"props":2396,"children":2397},{"class":560,"line":561},[2398,2402,2407,2411,2416,2421,2426,2430,2435],{"type":414,"tag":558,"props":2399,"children":2400},{"style":670},[2401],{"type":419,"value":1514},{"type":414,"tag":558,"props":2403,"children":2404},{"style":565},[2405],{"type":419,"value":2406},"github ",{"type":414,"tag":558,"props":2408,"children":2409},{"style":670},[2410],{"type":419,"value":2310},{"type":414,"tag":558,"props":2412,"children":2413},{"style":730},[2414],{"type":419,"value":2415}," Get-Content",{"type":414,"tag":558,"props":2417,"children":2418},{"style":670},[2419],{"type":419,"value":2420}," '",{"type":414,"tag":558,"props":2422,"children":2423},{"style":696},[2424],{"type":419,"value":2425},"${{ github.event_path }}",{"type":414,"tag":558,"props":2427,"children":2428},{"style":670},[2429],{"type":419,"value":2343},{"type":414,"tag":558,"props":2431,"children":2432},{"style":670},[2433],{"type":419,"value":2434}," |",{"type":414,"tag":558,"props":2436,"children":2437},{"style":730},[2438],{"type":419,"value":2439}," ConvertFrom-Json\n",{"type":414,"tag":558,"props":2441,"children":2442},{"class":560,"line":661},[2443,2447,2451,2455,2459,2464,2468,2473,2477,2482,2487,2491,2496,2500,2504,2509,2513,2518,2522,2527],{"type":414,"tag":558,"props":2444,"children":2445},{"style":670},[2446],{"type":419,"value":1514},{"type":414,"tag":558,"props":2448,"children":2449},{"style":565},[2450],{"type":419,"value":2305},{"type":414,"tag":558,"props":2452,"children":2453},{"style":670},[2454],{"type":419,"value":2310},{"type":414,"tag":558,"props":2456,"children":2457},{"style":670},[2458],{"type":419,"value":1535},{"type":414,"tag":558,"props":2460,"children":2461},{"style":565},[2462],{"type":419,"value":2463},"github.release.assets ",{"type":414,"tag":558,"props":2465,"children":2466},{"style":670},[2467],{"type":419,"value":1554},{"type":414,"tag":558,"props":2469,"children":2470},{"style":730},[2471],{"type":419,"value":2472}," Where-Object",{"type":414,"tag":558,"props":2474,"children":2475},{"style":670},[2476],{"type":419,"value":1572},{"type":414,"tag":558,"props":2478,"children":2479},{"style":565},[2480],{"type":419,"value":2481},"Property name ",{"type":414,"tag":558,"props":2483,"children":2484},{"style":670},[2485],{"type":419,"value":2486},"-match",{"type":414,"tag":558,"props":2488,"children":2489},{"style":670},[2490],{"type":419,"value":2420},{"type":414,"tag":558,"props":2492,"children":2493},{"style":696},[2494],{"type":419,"value":2495},"windows.msi",{"type":414,"tag":558,"props":2497,"children":2498},{"style":670},[2499],{"type":419,"value":2343},{"type":414,"tag":558,"props":2501,"children":2502},{"style":670},[2503],{"type":419,"value":2434},{"type":414,"tag":558,"props":2505,"children":2506},{"style":565},[2507],{"type":419,"value":2508}," Select ",{"type":414,"tag":558,"props":2510,"children":2511},{"style":670},[2512],{"type":419,"value":673},{"type":414,"tag":558,"props":2514,"children":2515},{"style":565},[2516],{"type":419,"value":2517},"ExpandProperty browser_download_url ",{"type":414,"tag":558,"props":2519,"children":2520},{"style":670},[2521],{"type":419,"value":673},{"type":414,"tag":558,"props":2523,"children":2524},{"style":565},[2525],{"type":419,"value":2526},"First ",{"type":414,"tag":558,"props":2528,"children":2529},{"style":915},[2530],{"type":419,"value":2531},"1\n",{"type":414,"tag":415,"props":2533,"children":2534},{},[2535,2537,2542,2544,2551],{"type":419,"value":2536},"I did not know about jq but I find it is a nice tool although the syntax is not that straightforward. Yet, I prefer the PowerShell way because it allows to directly manipulate an object instead of a JSON string. It is what I did to automate the upgrade of the ",{"type":414,"tag":554,"props":2538,"children":2540},{"className":2539},[],[2541],{"type":419,"value":1042},{"type":419,"value":2543}," winget package using GitHub Actions when a new release is published (you can read more about it in this ",{"type":414,"tag":460,"props":2545,"children":2548},{"href":2546,"rel":2547},"https://www.techwatching.dev/posts/wingetcreate",[464],[2549],{"type":419,"value":2550},"article",{"type":419,"value":2552},").",{"type":414,"tag":421,"props":2554,"children":2556},{"id":2555},"tip-n4-enable-debugging-logs-to-help-you-understand-what-is-going-wrong-in-your-workflow",[2557],{"type":419,"value":2558},"Tip n°4: Enable debugging logs to help you understand what is going wrong in your workflow",{"type":414,"tag":415,"props":2560,"children":2561},{},[2562],{"type":419,"value":2563},"Like many CI / CD platforms, GitHub Actions has the disadvantage of not being testable locally which makes it hard to debug a workflow when something is not working properly. Moreover, by default, you won't see how some expressions/contexts are evaluated when the workflow run so logs will not help you figure out what is wrong in your workflow definition.",{"type":414,"tag":415,"props":2565,"children":2566},{},[2567,2569,2575,2577,2583],{"type":419,"value":2568},"Hopefully, you can enable debugging logs for all pipelines in your repository (unfortunately you can't specify it for a specific pipeline only) by setting the secret ",{"type":414,"tag":554,"props":2570,"children":2572},{"className":2571},[],[2573],{"type":419,"value":2574},"ACTIONS_STEP_DEBUG",{"type":419,"value":2576}," to true in your repository. You can read more about it in the ",{"type":414,"tag":460,"props":2578,"children":2581},{"href":2579,"rel":2580},"https://docs.github.com/en/actions/monitoring-and-troubleshooting-workflows/enabling-debug-logging",[464],[2582],{"type":419,"value":2210},{"type":419,"value":2584}," but here is what it look likes in a workflow run:",{"type":414,"tag":415,"props":2586,"children":2587},{},[2588],{"type":414,"tag":441,"props":2589,"children":2593},{"alt":2590,"className":2591,"src":2592},"Debug logs of a Github workflow run.",[445,446],"/posts/images/githubactions_logs_1.png",[],{"type":414,"tag":2595,"props":2596,"children":2597},"hr",{},[],{"type":414,"tag":415,"props":2599,"children":2600},{},[2601],{"type":419,"value":2602},"I hope these 4 tips will help you build awesome GitHub Actions workflows.",{"type":414,"tag":1957,"props":2604,"children":2605},{},[2606],{"type":419,"value":1961},{"title":401,"searchDepth":661,"depth":661,"links":2608},[2609,2610,2612,2613],{"id":2004,"depth":661,"text":2007},{"id":2075,"depth":661,"text":2611},"Tip n°2: Do not use your repository GITHUB_TOKEN in tasks that need to trigger another workflow.",{"id":2164,"depth":661,"text":2167},{"id":2555,"depth":661,"text":2558},"content:1.posts:22.github-actions-var-and-context.md","1.posts/22.github-actions-var-and-context.md",{"_path":28,"_dir":399,"_draft":400,"_partial":400,"_locale":401,"title":27,"description":2617,"lead":2618,"date":2619,"image":2620,"badge":2622,"tags":2623,"body":2624,"_type":1975,"_id":6662,"_source":1977,"_file":6663,"_extension":1979},"If you have no interest in reading the blog post and just want the final script, you can find it on this GitHub repository.","Creating a PowerShell script to configure SSO for the tab of a Teams application.","2020-06-15T00:00:00.000Z",{"src":2621},"/images/shell_1.jpg",{"label":266},[246,249,252],{"type":411,"children":2625,"toc":6647},[2626,2639,2643,2656,2670,2676,2699,2704,2710,2724,2905,2910,2916,2921,2967,2980,3012,3018,3031,3087,3093,3106,3207,3213,3233,3594,3606,4074,4080,4085,4435,4440,4674,4680,4693,4894,4907,5567,5586,6016,6022,6035,6040,6242,6262,6625,6631,6643],{"type":414,"tag":415,"props":2627,"children":2628},{},[2629,2631,2638],{"type":419,"value":2630},"If you have no interest in reading the blog post and just want the final script, you can find it on this ",{"type":414,"tag":460,"props":2632,"children":2635},{"href":2633,"rel":2634},"https://github.com/TechWatching/TeamsDev/blob/master/infra/Scripts/ConfigureTeamsTabSSO.ps1",[464],[2636],{"type":419,"value":2637},"GitHub repository",{"type":419,"value":597},{"type":414,"tag":421,"props":2640,"children":2641},{"id":423},[2642],{"type":419,"value":426},{"type":414,"tag":415,"props":2644,"children":2645},{},[2646,2648,2654],{"type":419,"value":2647},"Several months ago, I supervised a student project aiming at developing a Teams application for my company. The application is mainly composed of a tab where Human Resources people can see information about arrivals and departures in the company. Once the project was finished and the first version of the application was available, I provisioned the application infrastructure on my company Azure tenant using ",{"type":414,"tag":460,"props":2649,"children":2652},{"href":2650,"rel":2651},"https://www.pulumi.com/",[464],[2653],{"type":419,"value":312},{"type":419,"value":2655}," which is a nice infrastructure as code platform.",{"type":414,"tag":415,"props":2657,"children":2658},{},[2659,2661,2668],{"type":419,"value":2660},"However, configuring Single Sign-On for the tab of the application did not seem possible with Pulumi as it internally uses Terraform Provider for AzureAD which at the time of writing doesn't have all functionalities necessary to configure this. The ",{"type":414,"tag":460,"props":2662,"children":2665},{"href":2663,"rel":2664},"http://aka.ms/teams-sso",[464],[2666],{"type":419,"value":2667},"documentation about SSO for Teams tab",{"type":419,"value":2669}," currently lists all the steps necessary to configure it from the Azure Portal, however, it mentions nothing about automating it, hence this blog post.",{"type":414,"tag":421,"props":2671,"children":2673},{"id":2672},"steps-to-create-the-powershell-script",[2674],{"type":419,"value":2675},"Steps to create the PowerShell script",{"type":414,"tag":415,"props":2677,"children":2678},{},[2679,2681,2688,2690,2697],{"type":419,"value":2680},"Usually, I prefer Azure CLI to PowerShell as I find it easier to find commands I need, but Azure CLI doesn't have yet the necessary commands. Most of the code comes from ",{"type":414,"tag":460,"props":2682,"children":2685},{"href":2683,"rel":2684},"https://github.com/Azure-Samples/active-directory-dotnet-native-aspnetcore-v2/blob/master/3.-Web-api-call-Microsoft-graph-for-personal-accounts/AppCreationScripts/Configure.ps1",[464],[2686],{"type":419,"value":2687},"this script",{"type":419,"value":2689}," located in a repository of the ",{"type":414,"tag":460,"props":2691,"children":2694},{"href":2692,"rel":2693},"https://github.com/Azure-Samples",[464],[2695],{"type":419,"value":2696},"Azure Samples GitHub organization",{"type":419,"value":2698},". I took only what was necessary for Teams Tab SSO, adapted it to use Microsoft Graph objects/commands, and added missing commands.",{"type":414,"tag":415,"props":2700,"children":2701},{},[2702],{"type":419,"value":2703},"I am not an expert in PowerShell so there might be things to improve in the final script, but I hope the following steps will help you to understand how to configure SSO for your Teams Tab.",{"type":414,"tag":791,"props":2705,"children":2707},{"id":2706},"interacting-with-azure-active-directory",[2708],{"type":419,"value":2709},"Interacting with Azure Active Directory",{"type":414,"tag":415,"props":2711,"children":2712},{},[2713,2715,2722],{"type":419,"value":2714},"PowerShell has a module called ",{"type":414,"tag":460,"props":2716,"children":2719},{"href":2717,"rel":2718},"https://docs.microsoft.com/en-us/powershell/module/azuread/?view=azureadps-2.0",[464],[2720],{"type":419,"value":2721},"AzureAd",{"type":419,"value":2723}," that allow us to interact with Azure Active Directory.\nThe first step is to install this module if not already installed, import it and authenticate to Azure AD to be able to use Active Directory commands once authenticated.",{"type":414,"tag":548,"props":2725,"children":2727},{"className":644,"code":2726,"language":248,"meta":401,"style":401},"if ($null -eq (Get-Module -ListAvailable -Name \"AzureAD\")) { \n    Install-Module -Name \"AzureAD\" -Force\n}\n\nImport-Module AzureAD\n\nConnect-AzureAD -TenantId $tenantId\n",[2728],{"type":414,"tag":554,"props":2729,"children":2730},{"__ignoreMap":401},[2731,2805,2842,2850,2859,2872,2879],{"type":414,"tag":558,"props":2732,"children":2733},{"class":560,"line":561},[2734,2739,2744,2749,2754,2759,2763,2768,2772,2777,2781,2786,2790,2795,2800],{"type":414,"tag":558,"props":2735,"children":2736},{"style":1463},[2737],{"type":419,"value":2738},"if",{"type":414,"tag":558,"props":2740,"children":2741},{"style":670},[2742],{"type":419,"value":2743}," ($null",{"type":414,"tag":558,"props":2745,"children":2746},{"style":670},[2747],{"type":419,"value":2748}," -eq",{"type":414,"tag":558,"props":2750,"children":2751},{"style":670},[2752],{"type":419,"value":2753}," (",{"type":414,"tag":558,"props":2755,"children":2756},{"style":730},[2757],{"type":419,"value":2758},"Get-Module",{"type":414,"tag":558,"props":2760,"children":2761},{"style":670},[2762],{"type":419,"value":1572},{"type":414,"tag":558,"props":2764,"children":2765},{"style":565},[2766],{"type":419,"value":2767},"ListAvailable ",{"type":414,"tag":558,"props":2769,"children":2770},{"style":670},[2771],{"type":419,"value":673},{"type":414,"tag":558,"props":2773,"children":2774},{"style":565},[2775],{"type":419,"value":2776},"Name ",{"type":414,"tag":558,"props":2778,"children":2779},{"style":670},[2780],{"type":419,"value":693},{"type":414,"tag":558,"props":2782,"children":2783},{"style":696},[2784],{"type":419,"value":2785},"AzureAD",{"type":414,"tag":558,"props":2787,"children":2788},{"style":670},[2789],{"type":419,"value":693},{"type":414,"tag":558,"props":2791,"children":2792},{"style":670},[2793],{"type":419,"value":2794},"))",{"type":414,"tag":558,"props":2796,"children":2797},{"style":670},[2798],{"type":419,"value":2799}," {",{"type":414,"tag":558,"props":2801,"children":2802},{"style":565},[2803],{"type":419,"value":2804}," \n",{"type":414,"tag":558,"props":2806,"children":2807},{"class":560,"line":661},[2808,2813,2817,2821,2825,2829,2833,2837],{"type":414,"tag":558,"props":2809,"children":2810},{"style":730},[2811],{"type":419,"value":2812},"    Install-Module",{"type":414,"tag":558,"props":2814,"children":2815},{"style":670},[2816],{"type":419,"value":1572},{"type":414,"tag":558,"props":2818,"children":2819},{"style":565},[2820],{"type":419,"value":2776},{"type":414,"tag":558,"props":2822,"children":2823},{"style":670},[2824],{"type":419,"value":693},{"type":414,"tag":558,"props":2826,"children":2827},{"style":696},[2828],{"type":419,"value":2785},{"type":414,"tag":558,"props":2830,"children":2831},{"style":670},[2832],{"type":419,"value":693},{"type":414,"tag":558,"props":2834,"children":2835},{"style":670},[2836],{"type":419,"value":1572},{"type":414,"tag":558,"props":2838,"children":2839},{"style":565},[2840],{"type":419,"value":2841},"Force\n",{"type":414,"tag":558,"props":2843,"children":2844},{"class":560,"line":707},[2845],{"type":414,"tag":558,"props":2846,"children":2847},{"style":670},[2848],{"type":419,"value":2849},"}\n",{"type":414,"tag":558,"props":2851,"children":2852},{"class":560,"line":716},[2853],{"type":414,"tag":558,"props":2854,"children":2856},{"emptyLinePlaceholder":2855},true,[2857],{"type":419,"value":2858},"\n",{"type":414,"tag":558,"props":2860,"children":2861},{"class":560,"line":1222},[2862,2867],{"type":414,"tag":558,"props":2863,"children":2864},{"style":730},[2865],{"type":419,"value":2866},"Import-Module",{"type":414,"tag":558,"props":2868,"children":2869},{"style":565},[2870],{"type":419,"value":2871}," AzureAD\n",{"type":414,"tag":558,"props":2873,"children":2874},{"class":560,"line":1255},[2875],{"type":414,"tag":558,"props":2876,"children":2877},{"emptyLinePlaceholder":2855},[2878],{"type":419,"value":2858},{"type":414,"tag":558,"props":2880,"children":2881},{"class":560,"line":1288},[2882,2887,2891,2896,2900],{"type":414,"tag":558,"props":2883,"children":2884},{"style":730},[2885],{"type":419,"value":2886},"Connect-AzureAD",{"type":414,"tag":558,"props":2888,"children":2889},{"style":670},[2890],{"type":419,"value":1572},{"type":414,"tag":558,"props":2892,"children":2893},{"style":565},[2894],{"type":419,"value":2895},"TenantId ",{"type":414,"tag":558,"props":2897,"children":2898},{"style":670},[2899],{"type":419,"value":1514},{"type":414,"tag":558,"props":2901,"children":2902},{"style":565},[2903],{"type":419,"value":2904},"tenantId\n",{"type":414,"tag":415,"props":2906,"children":2907},{},[2908],{"type":419,"value":2909},"This will prompt us to log in with our AD account. We will see later in the article how we can avoid that if we are using this script in an Azure Pipeline.",{"type":414,"tag":791,"props":2911,"children":2913},{"id":2912},"retrieving-the-application-registration",[2914],{"type":419,"value":2915},"Retrieving the application registration",{"type":414,"tag":415,"props":2917,"children":2918},{},[2919],{"type":419,"value":2920},"I already created my application registration in AD with Pulumi so I just have to retrieve it before configuring it.",{"type":414,"tag":548,"props":2922,"children":2924},{"className":644,"code":2923,"language":248,"meta":401,"style":401},"$app = Get-AzureADMSApplication -ObjectId $applicationObjectId\n",[2925],{"type":414,"tag":554,"props":2926,"children":2927},{"__ignoreMap":401},[2928],{"type":414,"tag":558,"props":2929,"children":2930},{"class":560,"line":561},[2931,2935,2940,2944,2949,2953,2958,2962],{"type":414,"tag":558,"props":2932,"children":2933},{"style":670},[2934],{"type":419,"value":1514},{"type":414,"tag":558,"props":2936,"children":2937},{"style":565},[2938],{"type":419,"value":2939},"app ",{"type":414,"tag":558,"props":2941,"children":2942},{"style":670},[2943],{"type":419,"value":2310},{"type":414,"tag":558,"props":2945,"children":2946},{"style":730},[2947],{"type":419,"value":2948}," Get-AzureADMSApplication",{"type":414,"tag":558,"props":2950,"children":2951},{"style":670},[2952],{"type":419,"value":1572},{"type":414,"tag":558,"props":2954,"children":2955},{"style":565},[2956],{"type":419,"value":2957},"ObjectId ",{"type":414,"tag":558,"props":2959,"children":2960},{"style":670},[2961],{"type":419,"value":1514},{"type":414,"tag":558,"props":2963,"children":2964},{"style":565},[2965],{"type":419,"value":2966},"applicationObjectId\n",{"type":414,"tag":415,"props":2968,"children":2969},{},[2970,2972,2978],{"type":419,"value":2971},"If you don't have an existing application registration you can create one with the ",{"type":414,"tag":554,"props":2973,"children":2975},{"className":2974},[],[2976],{"type":419,"value":2977},"New-AzureADMSApplication",{"type":419,"value":2979}," command.",{"type":414,"tag":608,"props":2981,"children":2983},{"icon":2982},"i-fluent-emoji-flat-gem-stone",[2984],{"type":414,"tag":415,"props":2985,"children":2986},{},[2987,2989,2995,2996,3002,3004,3010],{"type":419,"value":2988},"You may note that there are similar commands ",{"type":414,"tag":554,"props":2990,"children":2992},{"className":2991},[],[2993],{"type":419,"value":2994},"Get-AzureADApplication",{"type":419,"value":810},{"type":414,"tag":554,"props":2997,"children":2999},{"className":2998},[],[3000],{"type":419,"value":3001},"New-AzureADApplication",{"type":419,"value":3003}," that exist. Both commands work fine but commands with ",{"type":414,"tag":3005,"props":3006,"children":3007},"em",{},[3008],{"type":419,"value":3009},"MS",{"type":419,"value":3011}," in their name internally use Microsoft Graph which seems to be the modern way to interact with Azure AD.",{"type":414,"tag":791,"props":3013,"children":3015},{"id":3014},"creating-the-service-principal",[3016],{"type":419,"value":3017},"Creating the service principal",{"type":414,"tag":415,"props":3019,"children":3020},{},[3021,3023,3030],{"type":419,"value":3022},"When you register an application in Azure Portal it creates an Application object and a Service Principal in your tenant. But if you create the Application outside the Azure Portal (Azure CLI, PowerShell, Pulumi, ...), you will have to create the Service Principal as well. Just as a reminder the ",{"type":414,"tag":460,"props":3024,"children":3027},{"href":3025,"rel":3026},"https://docs.microsoft.com/en-us/azure/active-directory/develop/app-objects-and-service-principals#application-and-service-principal-relationship",[464],[3028],{"type":419,"value":3029},"application object should be considered as the global representation of your application for use across all tenants, and the service principal as the local representation for use in a specific tenant",{"type":419,"value":597},{"type":414,"tag":548,"props":3032,"children":3034},{"className":644,"code":3033,"language":248,"meta":401,"style":401},"New-AzureADServicePrincipal -AppId $app.AppId -Tags {WindowsAzureActiveDirectoryIntegratedApp}\n",[3035],{"type":414,"tag":554,"props":3036,"children":3037},{"__ignoreMap":401},[3038],{"type":414,"tag":558,"props":3039,"children":3040},{"class":560,"line":561},[3041,3046,3050,3055,3059,3064,3068,3073,3078,3083],{"type":414,"tag":558,"props":3042,"children":3043},{"style":730},[3044],{"type":419,"value":3045},"New-AzureADServicePrincipal",{"type":414,"tag":558,"props":3047,"children":3048},{"style":670},[3049],{"type":419,"value":1572},{"type":414,"tag":558,"props":3051,"children":3052},{"style":565},[3053],{"type":419,"value":3054},"AppId ",{"type":414,"tag":558,"props":3056,"children":3057},{"style":670},[3058],{"type":419,"value":1514},{"type":414,"tag":558,"props":3060,"children":3061},{"style":565},[3062],{"type":419,"value":3063},"app.AppId ",{"type":414,"tag":558,"props":3065,"children":3066},{"style":670},[3067],{"type":419,"value":673},{"type":414,"tag":558,"props":3069,"children":3070},{"style":565},[3071],{"type":419,"value":3072},"Tags ",{"type":414,"tag":558,"props":3074,"children":3075},{"style":670},[3076],{"type":419,"value":3077},"{",{"type":414,"tag":558,"props":3079,"children":3080},{"style":565},[3081],{"type":419,"value":3082},"WindowsAzureActiveDirectoryIntegratedApp",{"type":414,"tag":558,"props":3084,"children":3085},{"style":670},[3086],{"type":419,"value":2849},{"type":414,"tag":791,"props":3088,"children":3090},{"id":3089},"exposing-an-application-as-an-api",[3091],{"type":419,"value":3092},"Exposing an application as an API",{"type":414,"tag":415,"props":3094,"children":3095},{},[3096,3098,3104],{"type":419,"value":3097},"To expose an application as an API, it is necessary to set the identifier URI of the application. We will use a variable ",{"type":414,"tag":554,"props":3099,"children":3101},{"className":3100},[],[3102],{"type":419,"value":3103},"$customDomainName",{"type":419,"value":3105}," to specify the custom domain of the application. Indeed as stated by the documentation, for the moment Teams Tab SSO does not support applications that use the azurewebsites.net domain.",{"type":414,"tag":548,"props":3107,"children":3109},{"className":644,"code":3108,"language":248,"meta":401,"style":401},"$appId = $app.AppId\nSet-AzureADMSApplication -ObjectId $app.Id -IdentifierUris \"api://$customDomainName/$appId\"\n",[3110],{"type":414,"tag":554,"props":3111,"children":3112},{"__ignoreMap":401},[3113,3138],{"type":414,"tag":558,"props":3114,"children":3115},{"class":560,"line":561},[3116,3120,3125,3129,3133],{"type":414,"tag":558,"props":3117,"children":3118},{"style":670},[3119],{"type":419,"value":1514},{"type":414,"tag":558,"props":3121,"children":3122},{"style":565},[3123],{"type":419,"value":3124},"appId ",{"type":414,"tag":558,"props":3126,"children":3127},{"style":670},[3128],{"type":419,"value":2310},{"type":414,"tag":558,"props":3130,"children":3131},{"style":670},[3132],{"type":419,"value":1535},{"type":414,"tag":558,"props":3134,"children":3135},{"style":565},[3136],{"type":419,"value":3137},"app.AppId\n",{"type":414,"tag":558,"props":3139,"children":3140},{"class":560,"line":661},[3141,3146,3150,3154,3158,3163,3167,3172,3176,3181,3185,3190,3194,3198,3203],{"type":414,"tag":558,"props":3142,"children":3143},{"style":730},[3144],{"type":419,"value":3145},"Set-AzureADMSApplication",{"type":414,"tag":558,"props":3147,"children":3148},{"style":670},[3149],{"type":419,"value":1572},{"type":414,"tag":558,"props":3151,"children":3152},{"style":565},[3153],{"type":419,"value":2957},{"type":414,"tag":558,"props":3155,"children":3156},{"style":670},[3157],{"type":419,"value":1514},{"type":414,"tag":558,"props":3159,"children":3160},{"style":565},[3161],{"type":419,"value":3162},"app.Id ",{"type":414,"tag":558,"props":3164,"children":3165},{"style":670},[3166],{"type":419,"value":673},{"type":414,"tag":558,"props":3168,"children":3169},{"style":565},[3170],{"type":419,"value":3171},"IdentifierUris ",{"type":414,"tag":558,"props":3173,"children":3174},{"style":670},[3175],{"type":419,"value":693},{"type":414,"tag":558,"props":3177,"children":3178},{"style":696},[3179],{"type":419,"value":3180},"api://",{"type":414,"tag":558,"props":3182,"children":3183},{"style":670},[3184],{"type":419,"value":1514},{"type":414,"tag":558,"props":3186,"children":3187},{"style":565},[3188],{"type":419,"value":3189},"customDomainName",{"type":414,"tag":558,"props":3191,"children":3192},{"style":696},[3193],{"type":419,"value":738},{"type":414,"tag":558,"props":3195,"children":3196},{"style":670},[3197],{"type":419,"value":1514},{"type":414,"tag":558,"props":3199,"children":3200},{"style":565},[3201],{"type":419,"value":3202},"appId",{"type":414,"tag":558,"props":3204,"children":3205},{"style":670},[3206],{"type":419,"value":704},{"type":414,"tag":791,"props":3208,"children":3210},{"id":3209},"creating-the-access_as_user-scope",[3211],{"type":419,"value":3212},"Creating the access_as_user scope",{"type":414,"tag":415,"props":3214,"children":3215},{},[3216,3218,3224,3226,3231],{"type":419,"value":3217},"Teams Tab SSO works by making the Teams client (whether it be Teams mobile app, desktop app, or web app) ask for an Azure AD token with the scope ",{"type":414,"tag":554,"props":3219,"children":3221},{"className":3220},[],[3222],{"type":419,"value":3223},"access_as_user",{"type":419,"value":3225}," of the Tab application you developed. So we need to create a scope ",{"type":414,"tag":554,"props":3227,"children":3229},{"className":3228},[],[3230],{"type":419,"value":3223},{"type":419,"value":3232}," in the application.",{"type":414,"tag":548,"props":3234,"children":3236},{"className":644,"code":3235,"language":248,"meta":401,"style":401},"# Add all existing scopes first\n$scopes = New-Object System.Collections.Generic.List[Microsoft.Open.MsGraph.Model.PermissionScope]\n$app.Api.Oauth2PermissionScopes | foreach-object { $scopes.Add($_) }\n$scope = CreateScope -value \"access_as_user\"  `\n    -userConsentDisplayName \"Teams can access the user’s profile\"  `\n    -userConsentDescription \"Allows Teams to call the app’s web APIs as the current user.\"  `\n    -adminConsentDisplayName \"Teams can access your user profile and make requests on your behalf\"  `\n    -adminConsentDescription \"Enable Teams to call this app’s APIs with the same rights that you have\"\n$scopes.Add($scope)\n$app.Api.Oauth2PermissionScopes = $scopes\nSet-AzureADMSApplication -ObjectId $app.Id -Api $app.Api\n",[3237],{"type":414,"tag":554,"props":3238,"children":3239},{"__ignoreMap":401},[3240,3248,3289,3343,3390,3420,3449,3478,3503,3527,3552],{"type":414,"tag":558,"props":3241,"children":3242},{"class":560,"line":561},[3243],{"type":414,"tag":558,"props":3244,"children":3245},{"style":655},[3246],{"type":419,"value":3247},"# Add all existing scopes first\n",{"type":414,"tag":558,"props":3249,"children":3250},{"class":560,"line":661},[3251,3255,3260,3264,3269,3274,3279,3284],{"type":414,"tag":558,"props":3252,"children":3253},{"style":670},[3254],{"type":419,"value":1514},{"type":414,"tag":558,"props":3256,"children":3257},{"style":565},[3258],{"type":419,"value":3259},"scopes ",{"type":414,"tag":558,"props":3261,"children":3262},{"style":670},[3263],{"type":419,"value":2310},{"type":414,"tag":558,"props":3265,"children":3266},{"style":730},[3267],{"type":419,"value":3268}," New-Object",{"type":414,"tag":558,"props":3270,"children":3271},{"style":565},[3272],{"type":419,"value":3273}," System.Collections.Generic.List",{"type":414,"tag":558,"props":3275,"children":3276},{"style":670},[3277],{"type":419,"value":3278},"[",{"type":414,"tag":558,"props":3280,"children":3281},{"style":1444},[3282],{"type":419,"value":3283},"Microsoft.Open.MsGraph.Model.PermissionScope",{"type":414,"tag":558,"props":3285,"children":3286},{"style":670},[3287],{"type":419,"value":3288},"]\n",{"type":414,"tag":558,"props":3290,"children":3291},{"class":560,"line":707},[3292,3296,3301,3305,3310,3314,3318,3323,3328,3333,3338],{"type":414,"tag":558,"props":3293,"children":3294},{"style":670},[3295],{"type":419,"value":1514},{"type":414,"tag":558,"props":3297,"children":3298},{"style":565},[3299],{"type":419,"value":3300},"app.Api.Oauth2PermissionScopes ",{"type":414,"tag":558,"props":3302,"children":3303},{"style":670},[3304],{"type":419,"value":1554},{"type":414,"tag":558,"props":3306,"children":3307},{"style":730},[3308],{"type":419,"value":3309}," foreach-object",{"type":414,"tag":558,"props":3311,"children":3312},{"style":670},[3313],{"type":419,"value":2799},{"type":414,"tag":558,"props":3315,"children":3316},{"style":670},[3317],{"type":419,"value":1535},{"type":414,"tag":558,"props":3319,"children":3320},{"style":565},[3321],{"type":419,"value":3322},"scopes.Add",{"type":414,"tag":558,"props":3324,"children":3325},{"style":670},[3326],{"type":419,"value":3327},"($",{"type":414,"tag":558,"props":3329,"children":3330},{"style":565},[3331],{"type":419,"value":3332},"_",{"type":414,"tag":558,"props":3334,"children":3335},{"style":670},[3336],{"type":419,"value":3337},")",{"type":414,"tag":558,"props":3339,"children":3340},{"style":670},[3341],{"type":419,"value":3342}," }\n",{"type":414,"tag":558,"props":3344,"children":3345},{"class":560,"line":716},[3346,3350,3355,3359,3364,3368,3373,3377,3381,3385],{"type":414,"tag":558,"props":3347,"children":3348},{"style":670},[3349],{"type":419,"value":1514},{"type":414,"tag":558,"props":3351,"children":3352},{"style":565},[3353],{"type":419,"value":3354},"scope ",{"type":414,"tag":558,"props":3356,"children":3357},{"style":670},[3358],{"type":419,"value":2310},{"type":414,"tag":558,"props":3360,"children":3361},{"style":565},[3362],{"type":419,"value":3363}," CreateScope ",{"type":414,"tag":558,"props":3365,"children":3366},{"style":670},[3367],{"type":419,"value":673},{"type":414,"tag":558,"props":3369,"children":3370},{"style":565},[3371],{"type":419,"value":3372},"value ",{"type":414,"tag":558,"props":3374,"children":3375},{"style":670},[3376],{"type":419,"value":693},{"type":414,"tag":558,"props":3378,"children":3379},{"style":696},[3380],{"type":419,"value":3223},{"type":414,"tag":558,"props":3382,"children":3383},{"style":670},[3384],{"type":419,"value":693},{"type":414,"tag":558,"props":3386,"children":3387},{"style":670},[3388],{"type":419,"value":3389},"  `\n",{"type":414,"tag":558,"props":3391,"children":3392},{"class":560,"line":1222},[3393,3398,3403,3407,3412,3416],{"type":414,"tag":558,"props":3394,"children":3395},{"style":670},[3396],{"type":419,"value":3397},"    -",{"type":414,"tag":558,"props":3399,"children":3400},{"style":565},[3401],{"type":419,"value":3402},"userConsentDisplayName ",{"type":414,"tag":558,"props":3404,"children":3405},{"style":670},[3406],{"type":419,"value":693},{"type":414,"tag":558,"props":3408,"children":3409},{"style":696},[3410],{"type":419,"value":3411},"Teams can access the user’s profile",{"type":414,"tag":558,"props":3413,"children":3414},{"style":670},[3415],{"type":419,"value":693},{"type":414,"tag":558,"props":3417,"children":3418},{"style":670},[3419],{"type":419,"value":3389},{"type":414,"tag":558,"props":3421,"children":3422},{"class":560,"line":1255},[3423,3427,3432,3436,3441,3445],{"type":414,"tag":558,"props":3424,"children":3425},{"style":670},[3426],{"type":419,"value":3397},{"type":414,"tag":558,"props":3428,"children":3429},{"style":565},[3430],{"type":419,"value":3431},"userConsentDescription ",{"type":414,"tag":558,"props":3433,"children":3434},{"style":670},[3435],{"type":419,"value":693},{"type":414,"tag":558,"props":3437,"children":3438},{"style":696},[3439],{"type":419,"value":3440},"Allows Teams to call the app’s web APIs as the current user.",{"type":414,"tag":558,"props":3442,"children":3443},{"style":670},[3444],{"type":419,"value":693},{"type":414,"tag":558,"props":3446,"children":3447},{"style":670},[3448],{"type":419,"value":3389},{"type":414,"tag":558,"props":3450,"children":3451},{"class":560,"line":1288},[3452,3456,3461,3465,3470,3474],{"type":414,"tag":558,"props":3453,"children":3454},{"style":670},[3455],{"type":419,"value":3397},{"type":414,"tag":558,"props":3457,"children":3458},{"style":565},[3459],{"type":419,"value":3460},"adminConsentDisplayName ",{"type":414,"tag":558,"props":3462,"children":3463},{"style":670},[3464],{"type":419,"value":693},{"type":414,"tag":558,"props":3466,"children":3467},{"style":696},[3468],{"type":419,"value":3469},"Teams can access your user profile and make requests on your behalf",{"type":414,"tag":558,"props":3471,"children":3472},{"style":670},[3473],{"type":419,"value":693},{"type":414,"tag":558,"props":3475,"children":3476},{"style":670},[3477],{"type":419,"value":3389},{"type":414,"tag":558,"props":3479,"children":3480},{"class":560,"line":1321},[3481,3485,3490,3494,3499],{"type":414,"tag":558,"props":3482,"children":3483},{"style":670},[3484],{"type":419,"value":3397},{"type":414,"tag":558,"props":3486,"children":3487},{"style":565},[3488],{"type":419,"value":3489},"adminConsentDescription ",{"type":414,"tag":558,"props":3491,"children":3492},{"style":670},[3493],{"type":419,"value":693},{"type":414,"tag":558,"props":3495,"children":3496},{"style":696},[3497],{"type":419,"value":3498},"Enable Teams to call this app’s APIs with the same rights that you have",{"type":414,"tag":558,"props":3500,"children":3501},{"style":670},[3502],{"type":419,"value":704},{"type":414,"tag":558,"props":3504,"children":3505},{"class":560,"line":1330},[3506,3510,3514,3518,3523],{"type":414,"tag":558,"props":3507,"children":3508},{"style":670},[3509],{"type":419,"value":1514},{"type":414,"tag":558,"props":3511,"children":3512},{"style":565},[3513],{"type":419,"value":3322},{"type":414,"tag":558,"props":3515,"children":3516},{"style":670},[3517],{"type":419,"value":3327},{"type":414,"tag":558,"props":3519,"children":3520},{"style":565},[3521],{"type":419,"value":3522},"scope",{"type":414,"tag":558,"props":3524,"children":3525},{"style":670},[3526],{"type":419,"value":1491},{"type":414,"tag":558,"props":3528,"children":3530},{"class":560,"line":3529},10,[3531,3535,3539,3543,3547],{"type":414,"tag":558,"props":3532,"children":3533},{"style":670},[3534],{"type":419,"value":1514},{"type":414,"tag":558,"props":3536,"children":3537},{"style":565},[3538],{"type":419,"value":3300},{"type":414,"tag":558,"props":3540,"children":3541},{"style":670},[3542],{"type":419,"value":2310},{"type":414,"tag":558,"props":3544,"children":3545},{"style":670},[3546],{"type":419,"value":1535},{"type":414,"tag":558,"props":3548,"children":3549},{"style":565},[3550],{"type":419,"value":3551},"scopes\n",{"type":414,"tag":558,"props":3553,"children":3555},{"class":560,"line":3554},11,[3556,3560,3564,3568,3572,3576,3580,3585,3589],{"type":414,"tag":558,"props":3557,"children":3558},{"style":730},[3559],{"type":419,"value":3145},{"type":414,"tag":558,"props":3561,"children":3562},{"style":670},[3563],{"type":419,"value":1572},{"type":414,"tag":558,"props":3565,"children":3566},{"style":565},[3567],{"type":419,"value":2957},{"type":414,"tag":558,"props":3569,"children":3570},{"style":670},[3571],{"type":419,"value":1514},{"type":414,"tag":558,"props":3573,"children":3574},{"style":565},[3575],{"type":419,"value":3162},{"type":414,"tag":558,"props":3577,"children":3578},{"style":670},[3579],{"type":419,"value":673},{"type":414,"tag":558,"props":3581,"children":3582},{"style":565},[3583],{"type":419,"value":3584},"Api ",{"type":414,"tag":558,"props":3586,"children":3587},{"style":670},[3588],{"type":419,"value":1514},{"type":414,"tag":558,"props":3590,"children":3591},{"style":565},[3592],{"type":419,"value":3593},"app.Api\n",{"type":414,"tag":415,"props":3595,"children":3596},{},[3597,3599,3604],{"type":419,"value":3598},"This piece of PowerShell just ensures existing scopes won't be deleted when adding the scope ",{"type":414,"tag":554,"props":3600,"children":3602},{"className":3601},[],[3603],{"type":419,"value":3223},{"type":419,"value":3605},". Display names and descriptions of the new scope are the ones recommended in the documentation. This code calls a PowerShell function that simply creates the scope object.",{"type":414,"tag":548,"props":3607,"children":3609},{"className":644,"code":3608,"language":248,"meta":401,"style":401},"\u003C#.Description\n   This function creates a new Azure AD scope (OAuth2Permission) with default and provided values\n#>  \nfunction CreateScope(\n    [string] $value,\n    [string] $userConsentDisplayName,\n    [string] $userConsentDescription,\n    [string] $adminConsentDisplayName,\n    [string] $adminConsentDescription)\n{\n    $scope = New-Object Microsoft.Open.MsGraph.Model.PermissionScope\n    $scope.Id = New-Guid\n    $scope.Value = $value\n    $scope.UserConsentDisplayName = $userConsentDisplayName\n    $scope.UserConsentDescription = $userConsentDescription\n    $scope.AdminConsentDisplayName = $adminConsentDisplayName\n    $scope.AdminConsentDescription = $adminConsentDescription\n    $scope.IsEnabled = $true\n    $scope.Type = \"User\"\n    return $scope\n}\n",[3610],{"type":414,"tag":554,"props":3611,"children":3612},{"__ignoreMap":401},[3613,3630,3638,3651,3668,3699,3727,3755,3783,3811,3819,3844,3866,3892,3918,3944,3970,3996,4018,4048,4066],{"type":414,"tag":558,"props":3614,"children":3615},{"class":560,"line":561},[3616,3621,3625],{"type":414,"tag":558,"props":3617,"children":3618},{"style":655},[3619],{"type":419,"value":3620},"\u003C#",{"type":414,"tag":558,"props":3622,"children":3623},{"style":655},[3624],{"type":419,"value":597},{"type":414,"tag":558,"props":3626,"children":3627},{"style":1463},[3628],{"type":419,"value":3629},"Description\n",{"type":414,"tag":558,"props":3631,"children":3632},{"class":560,"line":661},[3633],{"type":414,"tag":558,"props":3634,"children":3635},{"style":655},[3636],{"type":419,"value":3637},"   This function creates a new Azure AD scope (OAuth2Permission) with default and provided values\n",{"type":414,"tag":558,"props":3639,"children":3640},{"class":560,"line":707},[3641,3646],{"type":414,"tag":558,"props":3642,"children":3643},{"style":655},[3644],{"type":419,"value":3645},"#>",{"type":414,"tag":558,"props":3647,"children":3648},{"style":565},[3649],{"type":419,"value":3650},"  \n",{"type":414,"tag":558,"props":3652,"children":3653},{"class":560,"line":716},[3654,3658,3663],{"type":414,"tag":558,"props":3655,"children":3656},{"style":1444},[3657],{"type":419,"value":1447},{"type":414,"tag":558,"props":3659,"children":3660},{"style":730},[3661],{"type":419,"value":3662}," CreateScope",{"type":414,"tag":558,"props":3664,"children":3665},{"style":670},[3666],{"type":419,"value":3667},"(\n",{"type":414,"tag":558,"props":3669,"children":3670},{"class":560,"line":1222},[3671,3676,3680,3685,3689,3694],{"type":414,"tag":558,"props":3672,"children":3673},{"style":670},[3674],{"type":419,"value":3675},"    [",{"type":414,"tag":558,"props":3677,"children":3678},{"style":1444},[3679],{"type":419,"value":1476},{"type":414,"tag":558,"props":3681,"children":3682},{"style":670},[3683],{"type":419,"value":3684},"]",{"type":414,"tag":558,"props":3686,"children":3687},{"style":670},[3688],{"type":419,"value":1535},{"type":414,"tag":558,"props":3690,"children":3691},{"style":565},[3692],{"type":419,"value":3693},"value",{"type":414,"tag":558,"props":3695,"children":3696},{"style":670},[3697],{"type":419,"value":3698},",\n",{"type":414,"tag":558,"props":3700,"children":3701},{"class":560,"line":1255},[3702,3706,3710,3714,3718,3723],{"type":414,"tag":558,"props":3703,"children":3704},{"style":670},[3705],{"type":419,"value":3675},{"type":414,"tag":558,"props":3707,"children":3708},{"style":1444},[3709],{"type":419,"value":1476},{"type":414,"tag":558,"props":3711,"children":3712},{"style":670},[3713],{"type":419,"value":3684},{"type":414,"tag":558,"props":3715,"children":3716},{"style":670},[3717],{"type":419,"value":1535},{"type":414,"tag":558,"props":3719,"children":3720},{"style":565},[3721],{"type":419,"value":3722},"userConsentDisplayName",{"type":414,"tag":558,"props":3724,"children":3725},{"style":670},[3726],{"type":419,"value":3698},{"type":414,"tag":558,"props":3728,"children":3729},{"class":560,"line":1288},[3730,3734,3738,3742,3746,3751],{"type":414,"tag":558,"props":3731,"children":3732},{"style":670},[3733],{"type":419,"value":3675},{"type":414,"tag":558,"props":3735,"children":3736},{"style":1444},[3737],{"type":419,"value":1476},{"type":414,"tag":558,"props":3739,"children":3740},{"style":670},[3741],{"type":419,"value":3684},{"type":414,"tag":558,"props":3743,"children":3744},{"style":670},[3745],{"type":419,"value":1535},{"type":414,"tag":558,"props":3747,"children":3748},{"style":565},[3749],{"type":419,"value":3750},"userConsentDescription",{"type":414,"tag":558,"props":3752,"children":3753},{"style":670},[3754],{"type":419,"value":3698},{"type":414,"tag":558,"props":3756,"children":3757},{"class":560,"line":1321},[3758,3762,3766,3770,3774,3779],{"type":414,"tag":558,"props":3759,"children":3760},{"style":670},[3761],{"type":419,"value":3675},{"type":414,"tag":558,"props":3763,"children":3764},{"style":1444},[3765],{"type":419,"value":1476},{"type":414,"tag":558,"props":3767,"children":3768},{"style":670},[3769],{"type":419,"value":3684},{"type":414,"tag":558,"props":3771,"children":3772},{"style":670},[3773],{"type":419,"value":1535},{"type":414,"tag":558,"props":3775,"children":3776},{"style":565},[3777],{"type":419,"value":3778},"adminConsentDisplayName",{"type":414,"tag":558,"props":3780,"children":3781},{"style":670},[3782],{"type":419,"value":3698},{"type":414,"tag":558,"props":3784,"children":3785},{"class":560,"line":1330},[3786,3790,3794,3798,3802,3807],{"type":414,"tag":558,"props":3787,"children":3788},{"style":670},[3789],{"type":419,"value":3675},{"type":414,"tag":558,"props":3791,"children":3792},{"style":1444},[3793],{"type":419,"value":1476},{"type":414,"tag":558,"props":3795,"children":3796},{"style":670},[3797],{"type":419,"value":3684},{"type":414,"tag":558,"props":3799,"children":3800},{"style":670},[3801],{"type":419,"value":1535},{"type":414,"tag":558,"props":3803,"children":3804},{"style":565},[3805],{"type":419,"value":3806},"adminConsentDescription",{"type":414,"tag":558,"props":3808,"children":3809},{"style":670},[3810],{"type":419,"value":1491},{"type":414,"tag":558,"props":3812,"children":3813},{"class":560,"line":3529},[3814],{"type":414,"tag":558,"props":3815,"children":3816},{"style":670},[3817],{"type":419,"value":3818},"{\n",{"type":414,"tag":558,"props":3820,"children":3821},{"class":560,"line":3554},[3822,3827,3831,3835,3839],{"type":414,"tag":558,"props":3823,"children":3824},{"style":670},[3825],{"type":419,"value":3826},"    $",{"type":414,"tag":558,"props":3828,"children":3829},{"style":565},[3830],{"type":419,"value":3354},{"type":414,"tag":558,"props":3832,"children":3833},{"style":670},[3834],{"type":419,"value":2310},{"type":414,"tag":558,"props":3836,"children":3837},{"style":730},[3838],{"type":419,"value":3268},{"type":414,"tag":558,"props":3840,"children":3841},{"style":565},[3842],{"type":419,"value":3843}," Microsoft.Open.MsGraph.Model.PermissionScope\n",{"type":414,"tag":558,"props":3845,"children":3847},{"class":560,"line":3846},12,[3848,3852,3857,3861],{"type":414,"tag":558,"props":3849,"children":3850},{"style":670},[3851],{"type":419,"value":3826},{"type":414,"tag":558,"props":3853,"children":3854},{"style":565},[3855],{"type":419,"value":3856},"scope.Id ",{"type":414,"tag":558,"props":3858,"children":3859},{"style":670},[3860],{"type":419,"value":2310},{"type":414,"tag":558,"props":3862,"children":3863},{"style":730},[3864],{"type":419,"value":3865}," New-Guid\n",{"type":414,"tag":558,"props":3867,"children":3869},{"class":560,"line":3868},13,[3870,3874,3879,3883,3887],{"type":414,"tag":558,"props":3871,"children":3872},{"style":670},[3873],{"type":419,"value":3826},{"type":414,"tag":558,"props":3875,"children":3876},{"style":565},[3877],{"type":419,"value":3878},"scope.Value ",{"type":414,"tag":558,"props":3880,"children":3881},{"style":670},[3882],{"type":419,"value":2310},{"type":414,"tag":558,"props":3884,"children":3885},{"style":670},[3886],{"type":419,"value":1535},{"type":414,"tag":558,"props":3888,"children":3889},{"style":565},[3890],{"type":419,"value":3891},"value\n",{"type":414,"tag":558,"props":3893,"children":3895},{"class":560,"line":3894},14,[3896,3900,3905,3909,3913],{"type":414,"tag":558,"props":3897,"children":3898},{"style":670},[3899],{"type":419,"value":3826},{"type":414,"tag":558,"props":3901,"children":3902},{"style":565},[3903],{"type":419,"value":3904},"scope.UserConsentDisplayName ",{"type":414,"tag":558,"props":3906,"children":3907},{"style":670},[3908],{"type":419,"value":2310},{"type":414,"tag":558,"props":3910,"children":3911},{"style":670},[3912],{"type":419,"value":1535},{"type":414,"tag":558,"props":3914,"children":3915},{"style":565},[3916],{"type":419,"value":3917},"userConsentDisplayName\n",{"type":414,"tag":558,"props":3919,"children":3921},{"class":560,"line":3920},15,[3922,3926,3931,3935,3939],{"type":414,"tag":558,"props":3923,"children":3924},{"style":670},[3925],{"type":419,"value":3826},{"type":414,"tag":558,"props":3927,"children":3928},{"style":565},[3929],{"type":419,"value":3930},"scope.UserConsentDescription ",{"type":414,"tag":558,"props":3932,"children":3933},{"style":670},[3934],{"type":419,"value":2310},{"type":414,"tag":558,"props":3936,"children":3937},{"style":670},[3938],{"type":419,"value":1535},{"type":414,"tag":558,"props":3940,"children":3941},{"style":565},[3942],{"type":419,"value":3943},"userConsentDescription\n",{"type":414,"tag":558,"props":3945,"children":3947},{"class":560,"line":3946},16,[3948,3952,3957,3961,3965],{"type":414,"tag":558,"props":3949,"children":3950},{"style":670},[3951],{"type":419,"value":3826},{"type":414,"tag":558,"props":3953,"children":3954},{"style":565},[3955],{"type":419,"value":3956},"scope.AdminConsentDisplayName ",{"type":414,"tag":558,"props":3958,"children":3959},{"style":670},[3960],{"type":419,"value":2310},{"type":414,"tag":558,"props":3962,"children":3963},{"style":670},[3964],{"type":419,"value":1535},{"type":414,"tag":558,"props":3966,"children":3967},{"style":565},[3968],{"type":419,"value":3969},"adminConsentDisplayName\n",{"type":414,"tag":558,"props":3971,"children":3973},{"class":560,"line":3972},17,[3974,3978,3983,3987,3991],{"type":414,"tag":558,"props":3975,"children":3976},{"style":670},[3977],{"type":419,"value":3826},{"type":414,"tag":558,"props":3979,"children":3980},{"style":565},[3981],{"type":419,"value":3982},"scope.AdminConsentDescription ",{"type":414,"tag":558,"props":3984,"children":3985},{"style":670},[3986],{"type":419,"value":2310},{"type":414,"tag":558,"props":3988,"children":3989},{"style":670},[3990],{"type":419,"value":1535},{"type":414,"tag":558,"props":3992,"children":3993},{"style":565},[3994],{"type":419,"value":3995},"adminConsentDescription\n",{"type":414,"tag":558,"props":3997,"children":3999},{"class":560,"line":3998},18,[4000,4004,4009,4013],{"type":414,"tag":558,"props":4001,"children":4002},{"style":670},[4003],{"type":419,"value":3826},{"type":414,"tag":558,"props":4005,"children":4006},{"style":565},[4007],{"type":419,"value":4008},"scope.IsEnabled ",{"type":414,"tag":558,"props":4010,"children":4011},{"style":670},[4012],{"type":419,"value":2310},{"type":414,"tag":558,"props":4014,"children":4015},{"style":670},[4016],{"type":419,"value":4017}," $true\n",{"type":414,"tag":558,"props":4019,"children":4021},{"class":560,"line":4020},19,[4022,4026,4031,4035,4039,4044],{"type":414,"tag":558,"props":4023,"children":4024},{"style":670},[4025],{"type":419,"value":3826},{"type":414,"tag":558,"props":4027,"children":4028},{"style":565},[4029],{"type":419,"value":4030},"scope.Type ",{"type":414,"tag":558,"props":4032,"children":4033},{"style":670},[4034],{"type":419,"value":2310},{"type":414,"tag":558,"props":4036,"children":4037},{"style":670},[4038],{"type":419,"value":1504},{"type":414,"tag":558,"props":4040,"children":4041},{"style":696},[4042],{"type":419,"value":4043},"User",{"type":414,"tag":558,"props":4045,"children":4046},{"style":670},[4047],{"type":419,"value":704},{"type":414,"tag":558,"props":4049,"children":4051},{"class":560,"line":4050},20,[4052,4057,4061],{"type":414,"tag":558,"props":4053,"children":4054},{"style":1463},[4055],{"type":419,"value":4056},"    return",{"type":414,"tag":558,"props":4058,"children":4059},{"style":670},[4060],{"type":419,"value":1535},{"type":414,"tag":558,"props":4062,"children":4063},{"style":565},[4064],{"type":419,"value":4065},"scope\n",{"type":414,"tag":558,"props":4067,"children":4069},{"class":560,"line":4068},21,[4070],{"type":414,"tag":558,"props":4071,"children":4072},{"style":670},[4073],{"type":419,"value":2849},{"type":414,"tag":791,"props":4075,"children":4077},{"id":4076},"preauthorize-teams-clients",[4078],{"type":419,"value":4079},"Preauthorize Teams clients.",{"type":414,"tag":415,"props":4081,"children":4082},{},[4083],{"type":419,"value":4084},"As the Teams clients will ask for a token with the previously created scope, they must be authorized to have access to this permission. That is what does the following script:",{"type":414,"tag":548,"props":4086,"children":4088},{"className":644,"code":4087,"language":248,"meta":401,"style":401},"# Authorize Teams mobile/desktop client and Teams web client to access API\n$preAuthorizedApplications = New-Object 'System.Collections.Generic.List[Microsoft.Open.MSGraph.ModePreAuthorizedApplication]'\n$teamsRichClienPreauthorization = CreatePreAuthorizedApplication `\n    -applicationIdToPreAuthorize '1fec8e78-bce4-4aaf-ab1b-5451cc387264' `\n    -scopeId $scope.Id\n$teamsWebClienPreauthorization = CreatePreAuthorizedApplication `\n    -applicationIdToPreAuthorize '5e3ce6c0-2b1f-4285-8d4b-75ee78787346' `\n    -scopeId $scope.Id\n$preAuthorizedApplications.Add($teamsRichClienPreauthorization)\n$preAuthorizedApplications.Add($teamsWebClienPreauthorization)   \n$app = Get-AzureADMSApplication -ObjectId $applicationObjectId\n$app.Api.PreAuthorizedApplications = $preAuthorizedApplications\nSet-AzureADMSApplication -ObjectId $app.Id -Api $app.Api\n",[4089],{"type":414,"tag":554,"props":4090,"children":4091},{"__ignoreMap":401},[4092,4100,4134,4160,4190,4211,4235,4263,4282,4307,4336,4371,4396],{"type":414,"tag":558,"props":4093,"children":4094},{"class":560,"line":561},[4095],{"type":414,"tag":558,"props":4096,"children":4097},{"style":655},[4098],{"type":419,"value":4099},"# Authorize Teams mobile/desktop client and Teams web client to access API\n",{"type":414,"tag":558,"props":4101,"children":4102},{"class":560,"line":661},[4103,4107,4112,4116,4120,4124,4129],{"type":414,"tag":558,"props":4104,"children":4105},{"style":670},[4106],{"type":419,"value":1514},{"type":414,"tag":558,"props":4108,"children":4109},{"style":565},[4110],{"type":419,"value":4111},"preAuthorizedApplications ",{"type":414,"tag":558,"props":4113,"children":4114},{"style":670},[4115],{"type":419,"value":2310},{"type":414,"tag":558,"props":4117,"children":4118},{"style":730},[4119],{"type":419,"value":3268},{"type":414,"tag":558,"props":4121,"children":4122},{"style":670},[4123],{"type":419,"value":2420},{"type":414,"tag":558,"props":4125,"children":4126},{"style":696},[4127],{"type":419,"value":4128},"System.Collections.Generic.List[Microsoft.Open.MSGraph.ModePreAuthorizedApplication]",{"type":414,"tag":558,"props":4130,"children":4131},{"style":670},[4132],{"type":419,"value":4133},"'\n",{"type":414,"tag":558,"props":4135,"children":4136},{"class":560,"line":707},[4137,4141,4146,4150,4155],{"type":414,"tag":558,"props":4138,"children":4139},{"style":670},[4140],{"type":419,"value":1514},{"type":414,"tag":558,"props":4142,"children":4143},{"style":565},[4144],{"type":419,"value":4145},"teamsRichClienPreauthorization ",{"type":414,"tag":558,"props":4147,"children":4148},{"style":670},[4149],{"type":419,"value":2310},{"type":414,"tag":558,"props":4151,"children":4152},{"style":565},[4153],{"type":419,"value":4154}," CreatePreAuthorizedApplication ",{"type":414,"tag":558,"props":4156,"children":4157},{"style":670},[4158],{"type":419,"value":4159},"`\n",{"type":414,"tag":558,"props":4161,"children":4162},{"class":560,"line":716},[4163,4167,4172,4176,4181,4185],{"type":414,"tag":558,"props":4164,"children":4165},{"style":670},[4166],{"type":419,"value":3397},{"type":414,"tag":558,"props":4168,"children":4169},{"style":565},[4170],{"type":419,"value":4171},"applicationIdToPreAuthorize ",{"type":414,"tag":558,"props":4173,"children":4174},{"style":670},[4175],{"type":419,"value":2343},{"type":414,"tag":558,"props":4177,"children":4178},{"style":696},[4179],{"type":419,"value":4180},"1fec8e78-bce4-4aaf-ab1b-5451cc387264",{"type":414,"tag":558,"props":4182,"children":4183},{"style":670},[4184],{"type":419,"value":2343},{"type":414,"tag":558,"props":4186,"children":4187},{"style":670},[4188],{"type":419,"value":4189}," `\n",{"type":414,"tag":558,"props":4191,"children":4192},{"class":560,"line":1222},[4193,4197,4202,4206],{"type":414,"tag":558,"props":4194,"children":4195},{"style":670},[4196],{"type":419,"value":3397},{"type":414,"tag":558,"props":4198,"children":4199},{"style":565},[4200],{"type":419,"value":4201},"scopeId ",{"type":414,"tag":558,"props":4203,"children":4204},{"style":670},[4205],{"type":419,"value":1514},{"type":414,"tag":558,"props":4207,"children":4208},{"style":565},[4209],{"type":419,"value":4210},"scope.Id\n",{"type":414,"tag":558,"props":4212,"children":4213},{"class":560,"line":1255},[4214,4218,4223,4227,4231],{"type":414,"tag":558,"props":4215,"children":4216},{"style":670},[4217],{"type":419,"value":1514},{"type":414,"tag":558,"props":4219,"children":4220},{"style":565},[4221],{"type":419,"value":4222},"teamsWebClienPreauthorization ",{"type":414,"tag":558,"props":4224,"children":4225},{"style":670},[4226],{"type":419,"value":2310},{"type":414,"tag":558,"props":4228,"children":4229},{"style":565},[4230],{"type":419,"value":4154},{"type":414,"tag":558,"props":4232,"children":4233},{"style":670},[4234],{"type":419,"value":4159},{"type":414,"tag":558,"props":4236,"children":4237},{"class":560,"line":1288},[4238,4242,4246,4250,4255,4259],{"type":414,"tag":558,"props":4239,"children":4240},{"style":670},[4241],{"type":419,"value":3397},{"type":414,"tag":558,"props":4243,"children":4244},{"style":565},[4245],{"type":419,"value":4171},{"type":414,"tag":558,"props":4247,"children":4248},{"style":670},[4249],{"type":419,"value":2343},{"type":414,"tag":558,"props":4251,"children":4252},{"style":696},[4253],{"type":419,"value":4254},"5e3ce6c0-2b1f-4285-8d4b-75ee78787346",{"type":414,"tag":558,"props":4256,"children":4257},{"style":670},[4258],{"type":419,"value":2343},{"type":414,"tag":558,"props":4260,"children":4261},{"style":670},[4262],{"type":419,"value":4189},{"type":414,"tag":558,"props":4264,"children":4265},{"class":560,"line":1321},[4266,4270,4274,4278],{"type":414,"tag":558,"props":4267,"children":4268},{"style":670},[4269],{"type":419,"value":3397},{"type":414,"tag":558,"props":4271,"children":4272},{"style":565},[4273],{"type":419,"value":4201},{"type":414,"tag":558,"props":4275,"children":4276},{"style":670},[4277],{"type":419,"value":1514},{"type":414,"tag":558,"props":4279,"children":4280},{"style":565},[4281],{"type":419,"value":4210},{"type":414,"tag":558,"props":4283,"children":4284},{"class":560,"line":1330},[4285,4289,4294,4298,4303],{"type":414,"tag":558,"props":4286,"children":4287},{"style":670},[4288],{"type":419,"value":1514},{"type":414,"tag":558,"props":4290,"children":4291},{"style":565},[4292],{"type":419,"value":4293},"preAuthorizedApplications.Add",{"type":414,"tag":558,"props":4295,"children":4296},{"style":670},[4297],{"type":419,"value":3327},{"type":414,"tag":558,"props":4299,"children":4300},{"style":565},[4301],{"type":419,"value":4302},"teamsRichClienPreauthorization",{"type":414,"tag":558,"props":4304,"children":4305},{"style":670},[4306],{"type":419,"value":1491},{"type":414,"tag":558,"props":4308,"children":4309},{"class":560,"line":3529},[4310,4314,4318,4322,4327,4331],{"type":414,"tag":558,"props":4311,"children":4312},{"style":670},[4313],{"type":419,"value":1514},{"type":414,"tag":558,"props":4315,"children":4316},{"style":565},[4317],{"type":419,"value":4293},{"type":414,"tag":558,"props":4319,"children":4320},{"style":670},[4321],{"type":419,"value":3327},{"type":414,"tag":558,"props":4323,"children":4324},{"style":565},[4325],{"type":419,"value":4326},"teamsWebClienPreauthorization",{"type":414,"tag":558,"props":4328,"children":4329},{"style":670},[4330],{"type":419,"value":3337},{"type":414,"tag":558,"props":4332,"children":4333},{"style":565},[4334],{"type":419,"value":4335},"   \n",{"type":414,"tag":558,"props":4337,"children":4338},{"class":560,"line":3554},[4339,4343,4347,4351,4355,4359,4363,4367],{"type":414,"tag":558,"props":4340,"children":4341},{"style":670},[4342],{"type":419,"value":1514},{"type":414,"tag":558,"props":4344,"children":4345},{"style":565},[4346],{"type":419,"value":2939},{"type":414,"tag":558,"props":4348,"children":4349},{"style":670},[4350],{"type":419,"value":2310},{"type":414,"tag":558,"props":4352,"children":4353},{"style":730},[4354],{"type":419,"value":2948},{"type":414,"tag":558,"props":4356,"children":4357},{"style":670},[4358],{"type":419,"value":1572},{"type":414,"tag":558,"props":4360,"children":4361},{"style":565},[4362],{"type":419,"value":2957},{"type":414,"tag":558,"props":4364,"children":4365},{"style":670},[4366],{"type":419,"value":1514},{"type":414,"tag":558,"props":4368,"children":4369},{"style":565},[4370],{"type":419,"value":2966},{"type":414,"tag":558,"props":4372,"children":4373},{"class":560,"line":3846},[4374,4378,4383,4387,4391],{"type":414,"tag":558,"props":4375,"children":4376},{"style":670},[4377],{"type":419,"value":1514},{"type":414,"tag":558,"props":4379,"children":4380},{"style":565},[4381],{"type":419,"value":4382},"app.Api.PreAuthorizedApplications ",{"type":414,"tag":558,"props":4384,"children":4385},{"style":670},[4386],{"type":419,"value":2310},{"type":414,"tag":558,"props":4388,"children":4389},{"style":670},[4390],{"type":419,"value":1535},{"type":414,"tag":558,"props":4392,"children":4393},{"style":565},[4394],{"type":419,"value":4395},"preAuthorizedApplications\n",{"type":414,"tag":558,"props":4397,"children":4398},{"class":560,"line":3868},[4399,4403,4407,4411,4415,4419,4423,4427,4431],{"type":414,"tag":558,"props":4400,"children":4401},{"style":730},[4402],{"type":419,"value":3145},{"type":414,"tag":558,"props":4404,"children":4405},{"style":670},[4406],{"type":419,"value":1572},{"type":414,"tag":558,"props":4408,"children":4409},{"style":565},[4410],{"type":419,"value":2957},{"type":414,"tag":558,"props":4412,"children":4413},{"style":670},[4414],{"type":419,"value":1514},{"type":414,"tag":558,"props":4416,"children":4417},{"style":565},[4418],{"type":419,"value":3162},{"type":414,"tag":558,"props":4420,"children":4421},{"style":670},[4422],{"type":419,"value":673},{"type":414,"tag":558,"props":4424,"children":4425},{"style":565},[4426],{"type":419,"value":3584},{"type":414,"tag":558,"props":4428,"children":4429},{"style":670},[4430],{"type":419,"value":1514},{"type":414,"tag":558,"props":4432,"children":4433},{"style":565},[4434],{"type":419,"value":3593},{"type":414,"tag":415,"props":4436,"children":4437},{},[4438],{"type":419,"value":4439},"This code calls a PowerShell function that simply creates the PreAuthorizedApplication object.",{"type":414,"tag":548,"props":4441,"children":4443},{"className":644,"code":4442,"language":248,"meta":401,"style":401},"\u003C#.Description\n   This function creates a new PreAuthorized application on a specified scope\n#>  \nfunction CreatePreAuthorizedApplication(\n    [string] $applicationIdToPreAuthorize,\n    [string] $scopeId)\n{\n    $preAuthorizedApplication = New-Object 'Microsoft.Open.MSGraph.Model.PreAuthorizedApplication'\n    $preAuthorizedApplication.AppId = $applicationIdToPreAuthorize\n    $preAuthorizedApplication.DelegatedPermissionIds = @($scopeId)\n    return $preAuthorizedApplication\n}\n",[4444],{"type":414,"tag":554,"props":4445,"children":4446},{"__ignoreMap":401},[4447,4462,4470,4481,4497,4525,4553,4560,4593,4618,4651,4667],{"type":414,"tag":558,"props":4448,"children":4449},{"class":560,"line":561},[4450,4454,4458],{"type":414,"tag":558,"props":4451,"children":4452},{"style":655},[4453],{"type":419,"value":3620},{"type":414,"tag":558,"props":4455,"children":4456},{"style":655},[4457],{"type":419,"value":597},{"type":414,"tag":558,"props":4459,"children":4460},{"style":1463},[4461],{"type":419,"value":3629},{"type":414,"tag":558,"props":4463,"children":4464},{"class":560,"line":661},[4465],{"type":414,"tag":558,"props":4466,"children":4467},{"style":655},[4468],{"type":419,"value":4469},"   This function creates a new PreAuthorized application on a specified scope\n",{"type":414,"tag":558,"props":4471,"children":4472},{"class":560,"line":707},[4473,4477],{"type":414,"tag":558,"props":4474,"children":4475},{"style":655},[4476],{"type":419,"value":3645},{"type":414,"tag":558,"props":4478,"children":4479},{"style":565},[4480],{"type":419,"value":3650},{"type":414,"tag":558,"props":4482,"children":4483},{"class":560,"line":716},[4484,4488,4493],{"type":414,"tag":558,"props":4485,"children":4486},{"style":1444},[4487],{"type":419,"value":1447},{"type":414,"tag":558,"props":4489,"children":4490},{"style":730},[4491],{"type":419,"value":4492}," CreatePreAuthorizedApplication",{"type":414,"tag":558,"props":4494,"children":4495},{"style":670},[4496],{"type":419,"value":3667},{"type":414,"tag":558,"props":4498,"children":4499},{"class":560,"line":1222},[4500,4504,4508,4512,4516,4521],{"type":414,"tag":558,"props":4501,"children":4502},{"style":670},[4503],{"type":419,"value":3675},{"type":414,"tag":558,"props":4505,"children":4506},{"style":1444},[4507],{"type":419,"value":1476},{"type":414,"tag":558,"props":4509,"children":4510},{"style":670},[4511],{"type":419,"value":3684},{"type":414,"tag":558,"props":4513,"children":4514},{"style":670},[4515],{"type":419,"value":1535},{"type":414,"tag":558,"props":4517,"children":4518},{"style":565},[4519],{"type":419,"value":4520},"applicationIdToPreAuthorize",{"type":414,"tag":558,"props":4522,"children":4523},{"style":670},[4524],{"type":419,"value":3698},{"type":414,"tag":558,"props":4526,"children":4527},{"class":560,"line":1255},[4528,4532,4536,4540,4544,4549],{"type":414,"tag":558,"props":4529,"children":4530},{"style":670},[4531],{"type":419,"value":3675},{"type":414,"tag":558,"props":4533,"children":4534},{"style":1444},[4535],{"type":419,"value":1476},{"type":414,"tag":558,"props":4537,"children":4538},{"style":670},[4539],{"type":419,"value":3684},{"type":414,"tag":558,"props":4541,"children":4542},{"style":670},[4543],{"type":419,"value":1535},{"type":414,"tag":558,"props":4545,"children":4546},{"style":565},[4547],{"type":419,"value":4548},"scopeId",{"type":414,"tag":558,"props":4550,"children":4551},{"style":670},[4552],{"type":419,"value":1491},{"type":414,"tag":558,"props":4554,"children":4555},{"class":560,"line":1288},[4556],{"type":414,"tag":558,"props":4557,"children":4558},{"style":670},[4559],{"type":419,"value":3818},{"type":414,"tag":558,"props":4561,"children":4562},{"class":560,"line":1321},[4563,4567,4572,4576,4580,4584,4589],{"type":414,"tag":558,"props":4564,"children":4565},{"style":670},[4566],{"type":419,"value":3826},{"type":414,"tag":558,"props":4568,"children":4569},{"style":565},[4570],{"type":419,"value":4571},"preAuthorizedApplication ",{"type":414,"tag":558,"props":4573,"children":4574},{"style":670},[4575],{"type":419,"value":2310},{"type":414,"tag":558,"props":4577,"children":4578},{"style":730},[4579],{"type":419,"value":3268},{"type":414,"tag":558,"props":4581,"children":4582},{"style":670},[4583],{"type":419,"value":2420},{"type":414,"tag":558,"props":4585,"children":4586},{"style":696},[4587],{"type":419,"value":4588},"Microsoft.Open.MSGraph.Model.PreAuthorizedApplication",{"type":414,"tag":558,"props":4590,"children":4591},{"style":670},[4592],{"type":419,"value":4133},{"type":414,"tag":558,"props":4594,"children":4595},{"class":560,"line":1330},[4596,4600,4605,4609,4613],{"type":414,"tag":558,"props":4597,"children":4598},{"style":670},[4599],{"type":419,"value":3826},{"type":414,"tag":558,"props":4601,"children":4602},{"style":565},[4603],{"type":419,"value":4604},"preAuthorizedApplication.AppId ",{"type":414,"tag":558,"props":4606,"children":4607},{"style":670},[4608],{"type":419,"value":2310},{"type":414,"tag":558,"props":4610,"children":4611},{"style":670},[4612],{"type":419,"value":1535},{"type":414,"tag":558,"props":4614,"children":4615},{"style":565},[4616],{"type":419,"value":4617},"applicationIdToPreAuthorize\n",{"type":414,"tag":558,"props":4619,"children":4620},{"class":560,"line":3529},[4621,4625,4630,4634,4639,4643,4647],{"type":414,"tag":558,"props":4622,"children":4623},{"style":670},[4624],{"type":419,"value":3826},{"type":414,"tag":558,"props":4626,"children":4627},{"style":565},[4628],{"type":419,"value":4629},"preAuthorizedApplication.DelegatedPermissionIds ",{"type":414,"tag":558,"props":4631,"children":4632},{"style":670},[4633],{"type":419,"value":2310},{"type":414,"tag":558,"props":4635,"children":4636},{"style":915},[4637],{"type":419,"value":4638}," @",{"type":414,"tag":558,"props":4640,"children":4641},{"style":670},[4642],{"type":419,"value":3327},{"type":414,"tag":558,"props":4644,"children":4645},{"style":565},[4646],{"type":419,"value":4548},{"type":414,"tag":558,"props":4648,"children":4649},{"style":670},[4650],{"type":419,"value":1491},{"type":414,"tag":558,"props":4652,"children":4653},{"class":560,"line":3554},[4654,4658,4662],{"type":414,"tag":558,"props":4655,"children":4656},{"style":1463},[4657],{"type":419,"value":4056},{"type":414,"tag":558,"props":4659,"children":4660},{"style":670},[4661],{"type":419,"value":1535},{"type":414,"tag":558,"props":4663,"children":4664},{"style":565},[4665],{"type":419,"value":4666},"preAuthorizedApplication\n",{"type":414,"tag":558,"props":4668,"children":4669},{"class":560,"line":3846},[4670],{"type":414,"tag":558,"props":4671,"children":4672},{"style":670},[4673],{"type":419,"value":2849},{"type":414,"tag":791,"props":4675,"children":4677},{"id":4676},"grant-user-level-graph-api-permissions",[4678],{"type":419,"value":4679},"Grant user-level Graph API permissions",{"type":414,"tag":415,"props":4681,"children":4682},{},[4683,4685,4692],{"type":419,"value":4684},"The next step consists in specifying the permissions the application will need for the AAD endpoint: email, offline_access, openid, profile (",{"type":414,"tag":460,"props":4686,"children":4689},{"href":4687,"rel":4688},"https://docs.microsoft.com/fr-fr/azure/active-directory/develop/v2-permissions-and-consent#openid-connect-scopes",[464],[4690],{"type":419,"value":4691},"OpenID connect scopes",{"type":419,"value":2552},{"type":414,"tag":548,"props":4694,"children":4696},{"className":644,"code":4695,"language":248,"meta":401,"style":401},"# Add API permissions needed\n$requiredResourcesAccess = New-Object System.Collections.Generic.List[Microsoft.Open.MsGraph.Model.RequiredResourceAccess]\n$requiredPermissions = GetRequiredPermissions `\n    -applicationDisplayName 'Microsoft Graph' `\n    -requiredDelegatedPermissions \"User.Read|email|offline_access|openid|profile\"\n$requiredResourcesAccess.Add($requiredPermissions)   \nSet-AzureADMSApplication -ObjectId $app.Id -RequiredResourceAccess $requiredPermissions\n",[4697],{"type":414,"tag":554,"props":4698,"children":4699},{"__ignoreMap":401},[4700,4708,4745,4770,4799,4824,4853],{"type":414,"tag":558,"props":4701,"children":4702},{"class":560,"line":561},[4703],{"type":414,"tag":558,"props":4704,"children":4705},{"style":655},[4706],{"type":419,"value":4707},"# Add API permissions needed\n",{"type":414,"tag":558,"props":4709,"children":4710},{"class":560,"line":661},[4711,4715,4720,4724,4728,4732,4736,4741],{"type":414,"tag":558,"props":4712,"children":4713},{"style":670},[4714],{"type":419,"value":1514},{"type":414,"tag":558,"props":4716,"children":4717},{"style":565},[4718],{"type":419,"value":4719},"requiredResourcesAccess ",{"type":414,"tag":558,"props":4721,"children":4722},{"style":670},[4723],{"type":419,"value":2310},{"type":414,"tag":558,"props":4725,"children":4726},{"style":730},[4727],{"type":419,"value":3268},{"type":414,"tag":558,"props":4729,"children":4730},{"style":565},[4731],{"type":419,"value":3273},{"type":414,"tag":558,"props":4733,"children":4734},{"style":670},[4735],{"type":419,"value":3278},{"type":414,"tag":558,"props":4737,"children":4738},{"style":1444},[4739],{"type":419,"value":4740},"Microsoft.Open.MsGraph.Model.RequiredResourceAccess",{"type":414,"tag":558,"props":4742,"children":4743},{"style":670},[4744],{"type":419,"value":3288},{"type":414,"tag":558,"props":4746,"children":4747},{"class":560,"line":707},[4748,4752,4757,4761,4766],{"type":414,"tag":558,"props":4749,"children":4750},{"style":670},[4751],{"type":419,"value":1514},{"type":414,"tag":558,"props":4753,"children":4754},{"style":565},[4755],{"type":419,"value":4756},"requiredPermissions ",{"type":414,"tag":558,"props":4758,"children":4759},{"style":670},[4760],{"type":419,"value":2310},{"type":414,"tag":558,"props":4762,"children":4763},{"style":565},[4764],{"type":419,"value":4765}," GetRequiredPermissions ",{"type":414,"tag":558,"props":4767,"children":4768},{"style":670},[4769],{"type":419,"value":4159},{"type":414,"tag":558,"props":4771,"children":4772},{"class":560,"line":716},[4773,4777,4782,4786,4791,4795],{"type":414,"tag":558,"props":4774,"children":4775},{"style":670},[4776],{"type":419,"value":3397},{"type":414,"tag":558,"props":4778,"children":4779},{"style":565},[4780],{"type":419,"value":4781},"applicationDisplayName ",{"type":414,"tag":558,"props":4783,"children":4784},{"style":670},[4785],{"type":419,"value":2343},{"type":414,"tag":558,"props":4787,"children":4788},{"style":696},[4789],{"type":419,"value":4790},"Microsoft Graph",{"type":414,"tag":558,"props":4792,"children":4793},{"style":670},[4794],{"type":419,"value":2343},{"type":414,"tag":558,"props":4796,"children":4797},{"style":670},[4798],{"type":419,"value":4189},{"type":414,"tag":558,"props":4800,"children":4801},{"class":560,"line":1222},[4802,4806,4811,4815,4820],{"type":414,"tag":558,"props":4803,"children":4804},{"style":670},[4805],{"type":419,"value":3397},{"type":414,"tag":558,"props":4807,"children":4808},{"style":565},[4809],{"type":419,"value":4810},"requiredDelegatedPermissions ",{"type":414,"tag":558,"props":4812,"children":4813},{"style":670},[4814],{"type":419,"value":693},{"type":414,"tag":558,"props":4816,"children":4817},{"style":696},[4818],{"type":419,"value":4819},"User.Read|email|offline_access|openid|profile",{"type":414,"tag":558,"props":4821,"children":4822},{"style":670},[4823],{"type":419,"value":704},{"type":414,"tag":558,"props":4825,"children":4826},{"class":560,"line":1255},[4827,4831,4836,4840,4845,4849],{"type":414,"tag":558,"props":4828,"children":4829},{"style":670},[4830],{"type":419,"value":1514},{"type":414,"tag":558,"props":4832,"children":4833},{"style":565},[4834],{"type":419,"value":4835},"requiredResourcesAccess.Add",{"type":414,"tag":558,"props":4837,"children":4838},{"style":670},[4839],{"type":419,"value":3327},{"type":414,"tag":558,"props":4841,"children":4842},{"style":565},[4843],{"type":419,"value":4844},"requiredPermissions",{"type":414,"tag":558,"props":4846,"children":4847},{"style":670},[4848],{"type":419,"value":3337},{"type":414,"tag":558,"props":4850,"children":4851},{"style":565},[4852],{"type":419,"value":4335},{"type":414,"tag":558,"props":4854,"children":4855},{"class":560,"line":1288},[4856,4860,4864,4868,4872,4876,4880,4885,4889],{"type":414,"tag":558,"props":4857,"children":4858},{"style":730},[4859],{"type":419,"value":3145},{"type":414,"tag":558,"props":4861,"children":4862},{"style":670},[4863],{"type":419,"value":1572},{"type":414,"tag":558,"props":4865,"children":4866},{"style":565},[4867],{"type":419,"value":2957},{"type":414,"tag":558,"props":4869,"children":4870},{"style":670},[4871],{"type":419,"value":1514},{"type":414,"tag":558,"props":4873,"children":4874},{"style":565},[4875],{"type":419,"value":3162},{"type":414,"tag":558,"props":4877,"children":4878},{"style":670},[4879],{"type":419,"value":673},{"type":414,"tag":558,"props":4881,"children":4882},{"style":565},[4883],{"type":419,"value":4884},"RequiredResourceAccess ",{"type":414,"tag":558,"props":4886,"children":4887},{"style":670},[4888],{"type":419,"value":1514},{"type":414,"tag":558,"props":4890,"children":4891},{"style":565},[4892],{"type":419,"value":4893},"requiredPermissions\n",{"type":414,"tag":415,"props":4895,"children":4896},{},[4897,4899,4905],{"type":419,"value":4898},"This code calls a PowerShell function ",{"type":414,"tag":554,"props":4900,"children":4902},{"className":4901},[],[4903],{"type":419,"value":4904},"GetRequiredPermissions",{"type":419,"value":4906}," that add the delegated or application permissions specified in parameter. Here we only ask for delegated permissions of Microsoft Graph needed to retrieve an OpenId Connect token but this function is generic and could be used to require scopes or roles of other APIs.",{"type":414,"tag":548,"props":4908,"children":4910},{"className":644,"code":4909,"language":248,"meta":401,"style":401},"# Example: GetRequiredPermissions \"Microsoft Graph\"  \"Graph.Read|User.Read\"\n# See also: http://stackoverflow.com/questions/42164581/how-to-configure-a-new-azure-ad-application-through-powershell\nfunction GetRequiredPermissions(\n    [string] $applicationDisplayName,\n    [string] $requiredDelegatedPermissions,\n    [string]$requiredApplicationPermissions,\n    $servicePrincipal)\n{\n    # If we are passed the service principal we use it directly, otherwise we find it from the display name (which might not be unique)\n    if ($servicePrincipal)\n    {\n        $sp = $servicePrincipal\n    }\n    else\n    {\n        $sp = Get-AzureADServicePrincipal -Filter \"DisplayName eq '$applicationDisplayName'\"\n    }\n\n    $requiredAccess = New-Object Microsoft.Open.MsGraph.Model.RequiredResourceAccess\n    $requiredAccess.ResourceAppId = $sp.AppId \n    $requiredAccess.ResourceAccess = New-Object System.Collections.Generic.List[Microsoft.Open.MsGraph.Model.ResourceAccess]\n\n    # $sp.Oauth2Permissions | Select Id,AdminConsentDisplayName,Value: To see the list of all the Delegated permissions for the application:\n    if ($requiredDelegatedPermissions)\n    {\n        AddResourcePermission $requiredAccess -exposedPermissions $sp.Oauth2Permissions -requiredAccesses $requiredDelegatedPermissions -permissionType \"Scope\"\n    }\n    \n    # $sp.AppRoles | Select Id,AdminConsentDisplayName,Value: To see the list of all the Application permissions for the application\n    if ($requiredApplicationPermissions)\n    {\n        AddResourcePermission $requiredAccess -exposedPermissions $sp.AppRoles -requiredAccesses $requiredApplicationPermissions -permissionType \"Role\"\n    }\n    return $requiredAccess\n}\n",[4911],{"type":414,"tag":554,"props":4912,"children":4913},{"__ignoreMap":401},[4914,4922,4930,4946,4974,5002,5026,5042,5049,5057,5078,5086,5112,5120,5128,5135,5189,5196,5203,5228,5253,5290,5298,5307,5327,5335,5409,5417,5426,5435,5455,5463,5534,5542,5559],{"type":414,"tag":558,"props":4915,"children":4916},{"class":560,"line":561},[4917],{"type":414,"tag":558,"props":4918,"children":4919},{"style":655},[4920],{"type":419,"value":4921},"# Example: GetRequiredPermissions \"Microsoft Graph\"  \"Graph.Read|User.Read\"\n",{"type":414,"tag":558,"props":4923,"children":4924},{"class":560,"line":661},[4925],{"type":414,"tag":558,"props":4926,"children":4927},{"style":655},[4928],{"type":419,"value":4929},"# See also: http://stackoverflow.com/questions/42164581/how-to-configure-a-new-azure-ad-application-through-powershell\n",{"type":414,"tag":558,"props":4931,"children":4932},{"class":560,"line":707},[4933,4937,4942],{"type":414,"tag":558,"props":4934,"children":4935},{"style":1444},[4936],{"type":419,"value":1447},{"type":414,"tag":558,"props":4938,"children":4939},{"style":730},[4940],{"type":419,"value":4941}," GetRequiredPermissions",{"type":414,"tag":558,"props":4943,"children":4944},{"style":670},[4945],{"type":419,"value":3667},{"type":414,"tag":558,"props":4947,"children":4948},{"class":560,"line":716},[4949,4953,4957,4961,4965,4970],{"type":414,"tag":558,"props":4950,"children":4951},{"style":670},[4952],{"type":419,"value":3675},{"type":414,"tag":558,"props":4954,"children":4955},{"style":1444},[4956],{"type":419,"value":1476},{"type":414,"tag":558,"props":4958,"children":4959},{"style":670},[4960],{"type":419,"value":3684},{"type":414,"tag":558,"props":4962,"children":4963},{"style":670},[4964],{"type":419,"value":1535},{"type":414,"tag":558,"props":4966,"children":4967},{"style":565},[4968],{"type":419,"value":4969},"applicationDisplayName",{"type":414,"tag":558,"props":4971,"children":4972},{"style":670},[4973],{"type":419,"value":3698},{"type":414,"tag":558,"props":4975,"children":4976},{"class":560,"line":1222},[4977,4981,4985,4989,4993,4998],{"type":414,"tag":558,"props":4978,"children":4979},{"style":670},[4980],{"type":419,"value":3675},{"type":414,"tag":558,"props":4982,"children":4983},{"style":1444},[4984],{"type":419,"value":1476},{"type":414,"tag":558,"props":4986,"children":4987},{"style":670},[4988],{"type":419,"value":3684},{"type":414,"tag":558,"props":4990,"children":4991},{"style":670},[4992],{"type":419,"value":1535},{"type":414,"tag":558,"props":4994,"children":4995},{"style":565},[4996],{"type":419,"value":4997},"requiredDelegatedPermissions",{"type":414,"tag":558,"props":4999,"children":5000},{"style":670},[5001],{"type":419,"value":3698},{"type":414,"tag":558,"props":5003,"children":5004},{"class":560,"line":1255},[5005,5009,5013,5017,5022],{"type":414,"tag":558,"props":5006,"children":5007},{"style":670},[5008],{"type":419,"value":3675},{"type":414,"tag":558,"props":5010,"children":5011},{"style":1444},[5012],{"type":419,"value":1476},{"type":414,"tag":558,"props":5014,"children":5015},{"style":670},[5016],{"type":419,"value":1481},{"type":414,"tag":558,"props":5018,"children":5019},{"style":565},[5020],{"type":419,"value":5021},"requiredApplicationPermissions",{"type":414,"tag":558,"props":5023,"children":5024},{"style":670},[5025],{"type":419,"value":3698},{"type":414,"tag":558,"props":5027,"children":5028},{"class":560,"line":1288},[5029,5033,5038],{"type":414,"tag":558,"props":5030,"children":5031},{"style":670},[5032],{"type":419,"value":3826},{"type":414,"tag":558,"props":5034,"children":5035},{"style":565},[5036],{"type":419,"value":5037},"servicePrincipal",{"type":414,"tag":558,"props":5039,"children":5040},{"style":670},[5041],{"type":419,"value":1491},{"type":414,"tag":558,"props":5043,"children":5044},{"class":560,"line":1321},[5045],{"type":414,"tag":558,"props":5046,"children":5047},{"style":670},[5048],{"type":419,"value":3818},{"type":414,"tag":558,"props":5050,"children":5051},{"class":560,"line":1330},[5052],{"type":414,"tag":558,"props":5053,"children":5054},{"style":655},[5055],{"type":419,"value":5056},"    # If we are passed the service principal we use it directly, otherwise we find it from the display name (which might not be unique)\n",{"type":414,"tag":558,"props":5058,"children":5059},{"class":560,"line":3529},[5060,5065,5070,5074],{"type":414,"tag":558,"props":5061,"children":5062},{"style":1463},[5063],{"type":419,"value":5064},"    if",{"type":414,"tag":558,"props":5066,"children":5067},{"style":670},[5068],{"type":419,"value":5069}," ($",{"type":414,"tag":558,"props":5071,"children":5072},{"style":565},[5073],{"type":419,"value":5037},{"type":414,"tag":558,"props":5075,"children":5076},{"style":670},[5077],{"type":419,"value":1491},{"type":414,"tag":558,"props":5079,"children":5080},{"class":560,"line":3554},[5081],{"type":414,"tag":558,"props":5082,"children":5083},{"style":670},[5084],{"type":419,"value":5085},"    {\n",{"type":414,"tag":558,"props":5087,"children":5088},{"class":560,"line":3846},[5089,5094,5099,5103,5107],{"type":414,"tag":558,"props":5090,"children":5091},{"style":670},[5092],{"type":419,"value":5093},"        $",{"type":414,"tag":558,"props":5095,"children":5096},{"style":565},[5097],{"type":419,"value":5098},"sp ",{"type":414,"tag":558,"props":5100,"children":5101},{"style":670},[5102],{"type":419,"value":2310},{"type":414,"tag":558,"props":5104,"children":5105},{"style":670},[5106],{"type":419,"value":1535},{"type":414,"tag":558,"props":5108,"children":5109},{"style":565},[5110],{"type":419,"value":5111},"servicePrincipal\n",{"type":414,"tag":558,"props":5113,"children":5114},{"class":560,"line":3868},[5115],{"type":414,"tag":558,"props":5116,"children":5117},{"style":670},[5118],{"type":419,"value":5119},"    }\n",{"type":414,"tag":558,"props":5121,"children":5122},{"class":560,"line":3894},[5123],{"type":414,"tag":558,"props":5124,"children":5125},{"style":1463},[5126],{"type":419,"value":5127},"    else\n",{"type":414,"tag":558,"props":5129,"children":5130},{"class":560,"line":3920},[5131],{"type":414,"tag":558,"props":5132,"children":5133},{"style":670},[5134],{"type":419,"value":5085},{"type":414,"tag":558,"props":5136,"children":5137},{"class":560,"line":3946},[5138,5142,5146,5150,5155,5159,5164,5168,5173,5177,5181,5185],{"type":414,"tag":558,"props":5139,"children":5140},{"style":670},[5141],{"type":419,"value":5093},{"type":414,"tag":558,"props":5143,"children":5144},{"style":565},[5145],{"type":419,"value":5098},{"type":414,"tag":558,"props":5147,"children":5148},{"style":670},[5149],{"type":419,"value":2310},{"type":414,"tag":558,"props":5151,"children":5152},{"style":730},[5153],{"type":419,"value":5154}," Get-AzureADServicePrincipal",{"type":414,"tag":558,"props":5156,"children":5157},{"style":670},[5158],{"type":419,"value":1572},{"type":414,"tag":558,"props":5160,"children":5161},{"style":565},[5162],{"type":419,"value":5163},"Filter ",{"type":414,"tag":558,"props":5165,"children":5166},{"style":670},[5167],{"type":419,"value":693},{"type":414,"tag":558,"props":5169,"children":5170},{"style":696},[5171],{"type":419,"value":5172},"DisplayName eq '",{"type":414,"tag":558,"props":5174,"children":5175},{"style":670},[5176],{"type":419,"value":1514},{"type":414,"tag":558,"props":5178,"children":5179},{"style":565},[5180],{"type":419,"value":4969},{"type":414,"tag":558,"props":5182,"children":5183},{"style":696},[5184],{"type":419,"value":2343},{"type":414,"tag":558,"props":5186,"children":5187},{"style":670},[5188],{"type":419,"value":704},{"type":414,"tag":558,"props":5190,"children":5191},{"class":560,"line":3972},[5192],{"type":414,"tag":558,"props":5193,"children":5194},{"style":670},[5195],{"type":419,"value":5119},{"type":414,"tag":558,"props":5197,"children":5198},{"class":560,"line":3998},[5199],{"type":414,"tag":558,"props":5200,"children":5201},{"emptyLinePlaceholder":2855},[5202],{"type":419,"value":2858},{"type":414,"tag":558,"props":5204,"children":5205},{"class":560,"line":4020},[5206,5210,5215,5219,5223],{"type":414,"tag":558,"props":5207,"children":5208},{"style":670},[5209],{"type":419,"value":3826},{"type":414,"tag":558,"props":5211,"children":5212},{"style":565},[5213],{"type":419,"value":5214},"requiredAccess ",{"type":414,"tag":558,"props":5216,"children":5217},{"style":670},[5218],{"type":419,"value":2310},{"type":414,"tag":558,"props":5220,"children":5221},{"style":730},[5222],{"type":419,"value":3268},{"type":414,"tag":558,"props":5224,"children":5225},{"style":565},[5226],{"type":419,"value":5227}," Microsoft.Open.MsGraph.Model.RequiredResourceAccess\n",{"type":414,"tag":558,"props":5229,"children":5230},{"class":560,"line":4050},[5231,5235,5240,5244,5248],{"type":414,"tag":558,"props":5232,"children":5233},{"style":670},[5234],{"type":419,"value":3826},{"type":414,"tag":558,"props":5236,"children":5237},{"style":565},[5238],{"type":419,"value":5239},"requiredAccess.ResourceAppId ",{"type":414,"tag":558,"props":5241,"children":5242},{"style":670},[5243],{"type":419,"value":2310},{"type":414,"tag":558,"props":5245,"children":5246},{"style":670},[5247],{"type":419,"value":1535},{"type":414,"tag":558,"props":5249,"children":5250},{"style":565},[5251],{"type":419,"value":5252},"sp.AppId \n",{"type":414,"tag":558,"props":5254,"children":5255},{"class":560,"line":4068},[5256,5260,5265,5269,5273,5277,5281,5286],{"type":414,"tag":558,"props":5257,"children":5258},{"style":670},[5259],{"type":419,"value":3826},{"type":414,"tag":558,"props":5261,"children":5262},{"style":565},[5263],{"type":419,"value":5264},"requiredAccess.ResourceAccess ",{"type":414,"tag":558,"props":5266,"children":5267},{"style":670},[5268],{"type":419,"value":2310},{"type":414,"tag":558,"props":5270,"children":5271},{"style":730},[5272],{"type":419,"value":3268},{"type":414,"tag":558,"props":5274,"children":5275},{"style":565},[5276],{"type":419,"value":3273},{"type":414,"tag":558,"props":5278,"children":5279},{"style":670},[5280],{"type":419,"value":3278},{"type":414,"tag":558,"props":5282,"children":5283},{"style":1444},[5284],{"type":419,"value":5285},"Microsoft.Open.MsGraph.Model.ResourceAccess",{"type":414,"tag":558,"props":5287,"children":5288},{"style":670},[5289],{"type":419,"value":3288},{"type":414,"tag":558,"props":5291,"children":5293},{"class":560,"line":5292},22,[5294],{"type":414,"tag":558,"props":5295,"children":5296},{"emptyLinePlaceholder":2855},[5297],{"type":419,"value":2858},{"type":414,"tag":558,"props":5299,"children":5301},{"class":560,"line":5300},23,[5302],{"type":414,"tag":558,"props":5303,"children":5304},{"style":655},[5305],{"type":419,"value":5306},"    # $sp.Oauth2Permissions | Select Id,AdminConsentDisplayName,Value: To see the list of all the Delegated permissions for the application:\n",{"type":414,"tag":558,"props":5308,"children":5310},{"class":560,"line":5309},24,[5311,5315,5319,5323],{"type":414,"tag":558,"props":5312,"children":5313},{"style":1463},[5314],{"type":419,"value":5064},{"type":414,"tag":558,"props":5316,"children":5317},{"style":670},[5318],{"type":419,"value":5069},{"type":414,"tag":558,"props":5320,"children":5321},{"style":565},[5322],{"type":419,"value":4997},{"type":414,"tag":558,"props":5324,"children":5325},{"style":670},[5326],{"type":419,"value":1491},{"type":414,"tag":558,"props":5328,"children":5330},{"class":560,"line":5329},25,[5331],{"type":414,"tag":558,"props":5332,"children":5333},{"style":670},[5334],{"type":419,"value":5085},{"type":414,"tag":558,"props":5336,"children":5338},{"class":560,"line":5337},26,[5339,5344,5348,5352,5356,5361,5365,5370,5374,5379,5383,5387,5391,5396,5400,5405],{"type":414,"tag":558,"props":5340,"children":5341},{"style":565},[5342],{"type":419,"value":5343},"        AddResourcePermission ",{"type":414,"tag":558,"props":5345,"children":5346},{"style":670},[5347],{"type":419,"value":1514},{"type":414,"tag":558,"props":5349,"children":5350},{"style":565},[5351],{"type":419,"value":5214},{"type":414,"tag":558,"props":5353,"children":5354},{"style":670},[5355],{"type":419,"value":673},{"type":414,"tag":558,"props":5357,"children":5358},{"style":565},[5359],{"type":419,"value":5360},"exposedPermissions ",{"type":414,"tag":558,"props":5362,"children":5363},{"style":670},[5364],{"type":419,"value":1514},{"type":414,"tag":558,"props":5366,"children":5367},{"style":565},[5368],{"type":419,"value":5369},"sp.Oauth2Permissions ",{"type":414,"tag":558,"props":5371,"children":5372},{"style":670},[5373],{"type":419,"value":673},{"type":414,"tag":558,"props":5375,"children":5376},{"style":565},[5377],{"type":419,"value":5378},"requiredAccesses ",{"type":414,"tag":558,"props":5380,"children":5381},{"style":670},[5382],{"type":419,"value":1514},{"type":414,"tag":558,"props":5384,"children":5385},{"style":565},[5386],{"type":419,"value":4810},{"type":414,"tag":558,"props":5388,"children":5389},{"style":670},[5390],{"type":419,"value":673},{"type":414,"tag":558,"props":5392,"children":5393},{"style":565},[5394],{"type":419,"value":5395},"permissionType ",{"type":414,"tag":558,"props":5397,"children":5398},{"style":670},[5399],{"type":419,"value":693},{"type":414,"tag":558,"props":5401,"children":5402},{"style":696},[5403],{"type":419,"value":5404},"Scope",{"type":414,"tag":558,"props":5406,"children":5407},{"style":670},[5408],{"type":419,"value":704},{"type":414,"tag":558,"props":5410,"children":5412},{"class":560,"line":5411},27,[5413],{"type":414,"tag":558,"props":5414,"children":5415},{"style":670},[5416],{"type":419,"value":5119},{"type":414,"tag":558,"props":5418,"children":5420},{"class":560,"line":5419},28,[5421],{"type":414,"tag":558,"props":5422,"children":5423},{"style":565},[5424],{"type":419,"value":5425},"    \n",{"type":414,"tag":558,"props":5427,"children":5429},{"class":560,"line":5428},29,[5430],{"type":414,"tag":558,"props":5431,"children":5432},{"style":655},[5433],{"type":419,"value":5434},"    # $sp.AppRoles | Select Id,AdminConsentDisplayName,Value: To see the list of all the Application permissions for the application\n",{"type":414,"tag":558,"props":5436,"children":5438},{"class":560,"line":5437},30,[5439,5443,5447,5451],{"type":414,"tag":558,"props":5440,"children":5441},{"style":1463},[5442],{"type":419,"value":5064},{"type":414,"tag":558,"props":5444,"children":5445},{"style":670},[5446],{"type":419,"value":5069},{"type":414,"tag":558,"props":5448,"children":5449},{"style":565},[5450],{"type":419,"value":5021},{"type":414,"tag":558,"props":5452,"children":5453},{"style":670},[5454],{"type":419,"value":1491},{"type":414,"tag":558,"props":5456,"children":5458},{"class":560,"line":5457},31,[5459],{"type":414,"tag":558,"props":5460,"children":5461},{"style":670},[5462],{"type":419,"value":5085},{"type":414,"tag":558,"props":5464,"children":5466},{"class":560,"line":5465},32,[5467,5471,5475,5479,5483,5487,5491,5496,5500,5504,5508,5513,5517,5521,5525,5530],{"type":414,"tag":558,"props":5468,"children":5469},{"style":565},[5470],{"type":419,"value":5343},{"type":414,"tag":558,"props":5472,"children":5473},{"style":670},[5474],{"type":419,"value":1514},{"type":414,"tag":558,"props":5476,"children":5477},{"style":565},[5478],{"type":419,"value":5214},{"type":414,"tag":558,"props":5480,"children":5481},{"style":670},[5482],{"type":419,"value":673},{"type":414,"tag":558,"props":5484,"children":5485},{"style":565},[5486],{"type":419,"value":5360},{"type":414,"tag":558,"props":5488,"children":5489},{"style":670},[5490],{"type":419,"value":1514},{"type":414,"tag":558,"props":5492,"children":5493},{"style":565},[5494],{"type":419,"value":5495},"sp.AppRoles ",{"type":414,"tag":558,"props":5497,"children":5498},{"style":670},[5499],{"type":419,"value":673},{"type":414,"tag":558,"props":5501,"children":5502},{"style":565},[5503],{"type":419,"value":5378},{"type":414,"tag":558,"props":5505,"children":5506},{"style":670},[5507],{"type":419,"value":1514},{"type":414,"tag":558,"props":5509,"children":5510},{"style":565},[5511],{"type":419,"value":5512},"requiredApplicationPermissions ",{"type":414,"tag":558,"props":5514,"children":5515},{"style":670},[5516],{"type":419,"value":673},{"type":414,"tag":558,"props":5518,"children":5519},{"style":565},[5520],{"type":419,"value":5395},{"type":414,"tag":558,"props":5522,"children":5523},{"style":670},[5524],{"type":419,"value":693},{"type":414,"tag":558,"props":5526,"children":5527},{"style":696},[5528],{"type":419,"value":5529},"Role",{"type":414,"tag":558,"props":5531,"children":5532},{"style":670},[5533],{"type":419,"value":704},{"type":414,"tag":558,"props":5535,"children":5537},{"class":560,"line":5536},33,[5538],{"type":414,"tag":558,"props":5539,"children":5540},{"style":670},[5541],{"type":419,"value":5119},{"type":414,"tag":558,"props":5543,"children":5545},{"class":560,"line":5544},34,[5546,5550,5554],{"type":414,"tag":558,"props":5547,"children":5548},{"style":1463},[5549],{"type":419,"value":4056},{"type":414,"tag":558,"props":5551,"children":5552},{"style":670},[5553],{"type":419,"value":1535},{"type":414,"tag":558,"props":5555,"children":5556},{"style":565},[5557],{"type":419,"value":5558},"requiredAccess\n",{"type":414,"tag":558,"props":5560,"children":5562},{"class":560,"line":5561},35,[5563],{"type":414,"tag":558,"props":5564,"children":5565},{"style":670},[5566],{"type":419,"value":2849},{"type":414,"tag":415,"props":5568,"children":5569},{},[5570,5571,5576,5578,5584],{"type":419,"value":572},{"type":414,"tag":554,"props":5572,"children":5574},{"className":5573},[],[5575],{"type":419,"value":4904},{"type":419,"value":5577}," function calls a ",{"type":414,"tag":554,"props":5579,"children":5581},{"className":5580},[],[5582],{"type":419,"value":5583},"AddResourcePermission",{"type":419,"value":5585}," function that creates permissions (ResourceAccess objects).",{"type":414,"tag":548,"props":5587,"children":5589},{"className":644,"code":5588,"language":248,"meta":401,"style":401},"# Adds the requiredAccesses (expressed as a pipe separated string) to the requiredAccess structure\n# The exposed permissions are in the $exposedPermissions collection, and the type of permission (Scope | Role) is \n# described in $permissionType\nfunction AddResourcePermission(\n    $requiredAccess,\n    $exposedPermissions,\n    [string]$requiredAccesses,\n    [string]$permissionType)\n{\n        foreach($permission in $requiredAccesses.Trim().Split(\"|\"))\n        {\n            foreach($exposedPermission in $exposedPermissions)\n            {\n                if ($exposedPermission.Value -eq $permission)\n                {\n                    $resourceAccess = New-Object Microsoft.Open.MsGraph.Model.ResourceAccess\n                    $resourceAccess.Type = $permissionType # Scope = Delegated permissions | Role = Application permissions\n                    $resourceAccess.Id = $exposedPermission.Id # Read directory data\n                    $requiredAccess.ResourceAccess.Add($resourceAccess)\n                }\n            }\n        }\n}\n",[5590],{"type":414,"tag":554,"props":5591,"children":5592},{"__ignoreMap":401},[5593,5601,5609,5617,5633,5649,5665,5689,5713,5720,5783,5791,5824,5832,5867,5875,5901,5930,5960,5985,5993,6001,6009],{"type":414,"tag":558,"props":5594,"children":5595},{"class":560,"line":561},[5596],{"type":414,"tag":558,"props":5597,"children":5598},{"style":655},[5599],{"type":419,"value":5600},"# Adds the requiredAccesses (expressed as a pipe separated string) to the requiredAccess structure\n",{"type":414,"tag":558,"props":5602,"children":5603},{"class":560,"line":661},[5604],{"type":414,"tag":558,"props":5605,"children":5606},{"style":655},[5607],{"type":419,"value":5608},"# The exposed permissions are in the $exposedPermissions collection, and the type of permission (Scope | Role) is \n",{"type":414,"tag":558,"props":5610,"children":5611},{"class":560,"line":707},[5612],{"type":414,"tag":558,"props":5613,"children":5614},{"style":655},[5615],{"type":419,"value":5616},"# described in $permissionType\n",{"type":414,"tag":558,"props":5618,"children":5619},{"class":560,"line":716},[5620,5624,5629],{"type":414,"tag":558,"props":5621,"children":5622},{"style":1444},[5623],{"type":419,"value":1447},{"type":414,"tag":558,"props":5625,"children":5626},{"style":730},[5627],{"type":419,"value":5628}," AddResourcePermission",{"type":414,"tag":558,"props":5630,"children":5631},{"style":670},[5632],{"type":419,"value":3667},{"type":414,"tag":558,"props":5634,"children":5635},{"class":560,"line":1222},[5636,5640,5645],{"type":414,"tag":558,"props":5637,"children":5638},{"style":670},[5639],{"type":419,"value":3826},{"type":414,"tag":558,"props":5641,"children":5642},{"style":565},[5643],{"type":419,"value":5644},"requiredAccess",{"type":414,"tag":558,"props":5646,"children":5647},{"style":670},[5648],{"type":419,"value":3698},{"type":414,"tag":558,"props":5650,"children":5651},{"class":560,"line":1255},[5652,5656,5661],{"type":414,"tag":558,"props":5653,"children":5654},{"style":670},[5655],{"type":419,"value":3826},{"type":414,"tag":558,"props":5657,"children":5658},{"style":565},[5659],{"type":419,"value":5660},"exposedPermissions",{"type":414,"tag":558,"props":5662,"children":5663},{"style":670},[5664],{"type":419,"value":3698},{"type":414,"tag":558,"props":5666,"children":5667},{"class":560,"line":1288},[5668,5672,5676,5680,5685],{"type":414,"tag":558,"props":5669,"children":5670},{"style":670},[5671],{"type":419,"value":3675},{"type":414,"tag":558,"props":5673,"children":5674},{"style":1444},[5675],{"type":419,"value":1476},{"type":414,"tag":558,"props":5677,"children":5678},{"style":670},[5679],{"type":419,"value":1481},{"type":414,"tag":558,"props":5681,"children":5682},{"style":565},[5683],{"type":419,"value":5684},"requiredAccesses",{"type":414,"tag":558,"props":5686,"children":5687},{"style":670},[5688],{"type":419,"value":3698},{"type":414,"tag":558,"props":5690,"children":5691},{"class":560,"line":1321},[5692,5696,5700,5704,5709],{"type":414,"tag":558,"props":5693,"children":5694},{"style":670},[5695],{"type":419,"value":3675},{"type":414,"tag":558,"props":5697,"children":5698},{"style":1444},[5699],{"type":419,"value":1476},{"type":414,"tag":558,"props":5701,"children":5702},{"style":670},[5703],{"type":419,"value":1481},{"type":414,"tag":558,"props":5705,"children":5706},{"style":565},[5707],{"type":419,"value":5708},"permissionType",{"type":414,"tag":558,"props":5710,"children":5711},{"style":670},[5712],{"type":419,"value":1491},{"type":414,"tag":558,"props":5714,"children":5715},{"class":560,"line":1330},[5716],{"type":414,"tag":558,"props":5717,"children":5718},{"style":670},[5719],{"type":419,"value":3818},{"type":414,"tag":558,"props":5721,"children":5722},{"class":560,"line":3529},[5723,5728,5732,5737,5742,5746,5751,5756,5761,5766,5770,5774,5778],{"type":414,"tag":558,"props":5724,"children":5725},{"style":1463},[5726],{"type":419,"value":5727},"        foreach",{"type":414,"tag":558,"props":5729,"children":5730},{"style":670},[5731],{"type":419,"value":3327},{"type":414,"tag":558,"props":5733,"children":5734},{"style":565},[5735],{"type":419,"value":5736},"permission ",{"type":414,"tag":558,"props":5738,"children":5739},{"style":1463},[5740],{"type":419,"value":5741},"in",{"type":414,"tag":558,"props":5743,"children":5744},{"style":670},[5745],{"type":419,"value":1535},{"type":414,"tag":558,"props":5747,"children":5748},{"style":565},[5749],{"type":419,"value":5750},"requiredAccesses.Trim",{"type":414,"tag":558,"props":5752,"children":5753},{"style":670},[5754],{"type":419,"value":5755},"()",{"type":414,"tag":558,"props":5757,"children":5758},{"style":565},[5759],{"type":419,"value":5760},".Split",{"type":414,"tag":558,"props":5762,"children":5763},{"style":670},[5764],{"type":419,"value":5765},"(",{"type":414,"tag":558,"props":5767,"children":5768},{"style":670},[5769],{"type":419,"value":693},{"type":414,"tag":558,"props":5771,"children":5772},{"style":696},[5773],{"type":419,"value":1554},{"type":414,"tag":558,"props":5775,"children":5776},{"style":670},[5777],{"type":419,"value":693},{"type":414,"tag":558,"props":5779,"children":5780},{"style":670},[5781],{"type":419,"value":5782},"))\n",{"type":414,"tag":558,"props":5784,"children":5785},{"class":560,"line":3554},[5786],{"type":414,"tag":558,"props":5787,"children":5788},{"style":670},[5789],{"type":419,"value":5790},"        {\n",{"type":414,"tag":558,"props":5792,"children":5793},{"class":560,"line":3846},[5794,5799,5803,5808,5812,5816,5820],{"type":414,"tag":558,"props":5795,"children":5796},{"style":1463},[5797],{"type":419,"value":5798},"            foreach",{"type":414,"tag":558,"props":5800,"children":5801},{"style":670},[5802],{"type":419,"value":3327},{"type":414,"tag":558,"props":5804,"children":5805},{"style":565},[5806],{"type":419,"value":5807},"exposedPermission ",{"type":414,"tag":558,"props":5809,"children":5810},{"style":1463},[5811],{"type":419,"value":5741},{"type":414,"tag":558,"props":5813,"children":5814},{"style":670},[5815],{"type":419,"value":1535},{"type":414,"tag":558,"props":5817,"children":5818},{"style":565},[5819],{"type":419,"value":5660},{"type":414,"tag":558,"props":5821,"children":5822},{"style":670},[5823],{"type":419,"value":1491},{"type":414,"tag":558,"props":5825,"children":5826},{"class":560,"line":3868},[5827],{"type":414,"tag":558,"props":5828,"children":5829},{"style":670},[5830],{"type":419,"value":5831},"            {\n",{"type":414,"tag":558,"props":5833,"children":5834},{"class":560,"line":3894},[5835,5840,5844,5849,5854,5858,5863],{"type":414,"tag":558,"props":5836,"children":5837},{"style":1463},[5838],{"type":419,"value":5839},"                if",{"type":414,"tag":558,"props":5841,"children":5842},{"style":670},[5843],{"type":419,"value":5069},{"type":414,"tag":558,"props":5845,"children":5846},{"style":565},[5847],{"type":419,"value":5848},"exposedPermission.Value ",{"type":414,"tag":558,"props":5850,"children":5851},{"style":670},[5852],{"type":419,"value":5853},"-eq",{"type":414,"tag":558,"props":5855,"children":5856},{"style":670},[5857],{"type":419,"value":1535},{"type":414,"tag":558,"props":5859,"children":5860},{"style":565},[5861],{"type":419,"value":5862},"permission",{"type":414,"tag":558,"props":5864,"children":5865},{"style":670},[5866],{"type":419,"value":1491},{"type":414,"tag":558,"props":5868,"children":5869},{"class":560,"line":3920},[5870],{"type":414,"tag":558,"props":5871,"children":5872},{"style":670},[5873],{"type":419,"value":5874},"                {\n",{"type":414,"tag":558,"props":5876,"children":5877},{"class":560,"line":3946},[5878,5883,5888,5892,5896],{"type":414,"tag":558,"props":5879,"children":5880},{"style":670},[5881],{"type":419,"value":5882},"                    $",{"type":414,"tag":558,"props":5884,"children":5885},{"style":565},[5886],{"type":419,"value":5887},"resourceAccess ",{"type":414,"tag":558,"props":5889,"children":5890},{"style":670},[5891],{"type":419,"value":2310},{"type":414,"tag":558,"props":5893,"children":5894},{"style":730},[5895],{"type":419,"value":3268},{"type":414,"tag":558,"props":5897,"children":5898},{"style":565},[5899],{"type":419,"value":5900}," Microsoft.Open.MsGraph.Model.ResourceAccess\n",{"type":414,"tag":558,"props":5902,"children":5903},{"class":560,"line":3972},[5904,5908,5913,5917,5921,5925],{"type":414,"tag":558,"props":5905,"children":5906},{"style":670},[5907],{"type":419,"value":5882},{"type":414,"tag":558,"props":5909,"children":5910},{"style":565},[5911],{"type":419,"value":5912},"resourceAccess.Type ",{"type":414,"tag":558,"props":5914,"children":5915},{"style":670},[5916],{"type":419,"value":2310},{"type":414,"tag":558,"props":5918,"children":5919},{"style":670},[5920],{"type":419,"value":1535},{"type":414,"tag":558,"props":5922,"children":5923},{"style":565},[5924],{"type":419,"value":5395},{"type":414,"tag":558,"props":5926,"children":5927},{"style":655},[5928],{"type":419,"value":5929},"# Scope = Delegated permissions | Role = Application permissions\n",{"type":414,"tag":558,"props":5931,"children":5932},{"class":560,"line":3998},[5933,5937,5942,5946,5950,5955],{"type":414,"tag":558,"props":5934,"children":5935},{"style":670},[5936],{"type":419,"value":5882},{"type":414,"tag":558,"props":5938,"children":5939},{"style":565},[5940],{"type":419,"value":5941},"resourceAccess.Id ",{"type":414,"tag":558,"props":5943,"children":5944},{"style":670},[5945],{"type":419,"value":2310},{"type":414,"tag":558,"props":5947,"children":5948},{"style":670},[5949],{"type":419,"value":1535},{"type":414,"tag":558,"props":5951,"children":5952},{"style":565},[5953],{"type":419,"value":5954},"exposedPermission.Id ",{"type":414,"tag":558,"props":5956,"children":5957},{"style":655},[5958],{"type":419,"value":5959},"# Read directory data\n",{"type":414,"tag":558,"props":5961,"children":5962},{"class":560,"line":4020},[5963,5967,5972,5976,5981],{"type":414,"tag":558,"props":5964,"children":5965},{"style":670},[5966],{"type":419,"value":5882},{"type":414,"tag":558,"props":5968,"children":5969},{"style":565},[5970],{"type":419,"value":5971},"requiredAccess.ResourceAccess.Add",{"type":414,"tag":558,"props":5973,"children":5974},{"style":670},[5975],{"type":419,"value":3327},{"type":414,"tag":558,"props":5977,"children":5978},{"style":565},[5979],{"type":419,"value":5980},"resourceAccess",{"type":414,"tag":558,"props":5982,"children":5983},{"style":670},[5984],{"type":419,"value":1491},{"type":414,"tag":558,"props":5986,"children":5987},{"class":560,"line":4050},[5988],{"type":414,"tag":558,"props":5989,"children":5990},{"style":670},[5991],{"type":419,"value":5992},"                }\n",{"type":414,"tag":558,"props":5994,"children":5995},{"class":560,"line":4068},[5996],{"type":414,"tag":558,"props":5997,"children":5998},{"style":670},[5999],{"type":419,"value":6000},"            }\n",{"type":414,"tag":558,"props":6002,"children":6003},{"class":560,"line":5292},[6004],{"type":414,"tag":558,"props":6005,"children":6006},{"style":670},[6007],{"type":419,"value":6008},"        }\n",{"type":414,"tag":558,"props":6010,"children":6011},{"class":560,"line":5300},[6012],{"type":414,"tag":558,"props":6013,"children":6014},{"style":670},[6015],{"type":419,"value":2849},{"type":414,"tag":421,"props":6017,"children":6019},{"id":6018},"using-the-script-in-an-azure-pipeline",[6020],{"type":419,"value":6021},"Using the script in an Azure Pipeline",{"type":414,"tag":415,"props":6023,"children":6024},{},[6025,6027,6034],{"type":419,"value":6026},"To execute this script in the Azure pipeline that deploys and configures the rest of the application infrastructure we can use an ",{"type":414,"tag":460,"props":6028,"children":6031},{"href":6029,"rel":6030},"https://docs.microsoft.com/en-us/azure/devops/pipelines/tasks/deploy/azure-powershell?view=azure-devops",[464],[6032],{"type":419,"value":6033},"Azure PowerShell task",{"type":419,"value":597},{"type":414,"tag":415,"props":6036,"children":6037},{},[6038],{"type":419,"value":6039},"The task of the Azure Pipeline will look like this:",{"type":414,"tag":548,"props":6041,"children":6045},{"className":6042,"code":6043,"language":6044,"meta":401,"style":401},"language-yaml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","- task: AzurePowerShell@5\n  displayName: 'Configure Teams tab SSO'\n  inputs:\n    azureSubscription: 'My Azure Service Connection'\n    ScriptType: 'FilePath'\n    ScriptPath: 'infra/AdditionalScripts/ConfigureTeamsTabSSO.ps1'\n    ScriptArguments: \n      -applicationObjectId $(AzureAdObjectId) `\n      -customDomainName $(CustomDomainName)\n    azurePowerShellVersion: 'LatestVersion'\n","yaml",[6046],{"type":414,"tag":554,"props":6047,"children":6048},{"__ignoreMap":401},[6049,6072,6097,6110,6135,6160,6185,6201,6209,6217],{"type":414,"tag":558,"props":6050,"children":6051},{"class":560,"line":561},[6052,6056,6062,6067],{"type":414,"tag":558,"props":6053,"children":6054},{"style":670},[6055],{"type":419,"value":673},{"type":414,"tag":558,"props":6057,"children":6059},{"style":6058},"--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178",[6060],{"type":419,"value":6061}," task",{"type":414,"tag":558,"props":6063,"children":6064},{"style":670},[6065],{"type":419,"value":6066},":",{"type":414,"tag":558,"props":6068,"children":6069},{"style":696},[6070],{"type":419,"value":6071}," AzurePowerShell@5\n",{"type":414,"tag":558,"props":6073,"children":6074},{"class":560,"line":661},[6075,6080,6084,6088,6093],{"type":414,"tag":558,"props":6076,"children":6077},{"style":6058},[6078],{"type":419,"value":6079},"  displayName",{"type":414,"tag":558,"props":6081,"children":6082},{"style":670},[6083],{"type":419,"value":6066},{"type":414,"tag":558,"props":6085,"children":6086},{"style":670},[6087],{"type":419,"value":2420},{"type":414,"tag":558,"props":6089,"children":6090},{"style":696},[6091],{"type":419,"value":6092},"Configure Teams tab SSO",{"type":414,"tag":558,"props":6094,"children":6095},{"style":670},[6096],{"type":419,"value":4133},{"type":414,"tag":558,"props":6098,"children":6099},{"class":560,"line":707},[6100,6105],{"type":414,"tag":558,"props":6101,"children":6102},{"style":6058},[6103],{"type":419,"value":6104},"  inputs",{"type":414,"tag":558,"props":6106,"children":6107},{"style":670},[6108],{"type":419,"value":6109},":\n",{"type":414,"tag":558,"props":6111,"children":6112},{"class":560,"line":716},[6113,6118,6122,6126,6131],{"type":414,"tag":558,"props":6114,"children":6115},{"style":6058},[6116],{"type":419,"value":6117},"    azureSubscription",{"type":414,"tag":558,"props":6119,"children":6120},{"style":670},[6121],{"type":419,"value":6066},{"type":414,"tag":558,"props":6123,"children":6124},{"style":670},[6125],{"type":419,"value":2420},{"type":414,"tag":558,"props":6127,"children":6128},{"style":696},[6129],{"type":419,"value":6130},"My Azure Service Connection",{"type":414,"tag":558,"props":6132,"children":6133},{"style":670},[6134],{"type":419,"value":4133},{"type":414,"tag":558,"props":6136,"children":6137},{"class":560,"line":1222},[6138,6143,6147,6151,6156],{"type":414,"tag":558,"props":6139,"children":6140},{"style":6058},[6141],{"type":419,"value":6142},"    ScriptType",{"type":414,"tag":558,"props":6144,"children":6145},{"style":670},[6146],{"type":419,"value":6066},{"type":414,"tag":558,"props":6148,"children":6149},{"style":670},[6150],{"type":419,"value":2420},{"type":414,"tag":558,"props":6152,"children":6153},{"style":696},[6154],{"type":419,"value":6155},"FilePath",{"type":414,"tag":558,"props":6157,"children":6158},{"style":670},[6159],{"type":419,"value":4133},{"type":414,"tag":558,"props":6161,"children":6162},{"class":560,"line":1255},[6163,6168,6172,6176,6181],{"type":414,"tag":558,"props":6164,"children":6165},{"style":6058},[6166],{"type":419,"value":6167},"    ScriptPath",{"type":414,"tag":558,"props":6169,"children":6170},{"style":670},[6171],{"type":419,"value":6066},{"type":414,"tag":558,"props":6173,"children":6174},{"style":670},[6175],{"type":419,"value":2420},{"type":414,"tag":558,"props":6177,"children":6178},{"style":696},[6179],{"type":419,"value":6180},"infra/AdditionalScripts/ConfigureTeamsTabSSO.ps1",{"type":414,"tag":558,"props":6182,"children":6183},{"style":670},[6184],{"type":419,"value":4133},{"type":414,"tag":558,"props":6186,"children":6187},{"class":560,"line":1288},[6188,6193,6197],{"type":414,"tag":558,"props":6189,"children":6190},{"style":6058},[6191],{"type":419,"value":6192},"    ScriptArguments",{"type":414,"tag":558,"props":6194,"children":6195},{"style":670},[6196],{"type":419,"value":6066},{"type":414,"tag":558,"props":6198,"children":6199},{"style":565},[6200],{"type":419,"value":2804},{"type":414,"tag":558,"props":6202,"children":6203},{"class":560,"line":1321},[6204],{"type":414,"tag":558,"props":6205,"children":6206},{"style":696},[6207],{"type":419,"value":6208},"      -applicationObjectId $(AzureAdObjectId) `\n",{"type":414,"tag":558,"props":6210,"children":6211},{"class":560,"line":1330},[6212],{"type":414,"tag":558,"props":6213,"children":6214},{"style":696},[6215],{"type":419,"value":6216},"      -customDomainName $(CustomDomainName)\n",{"type":414,"tag":558,"props":6218,"children":6219},{"class":560,"line":3529},[6220,6225,6229,6233,6238],{"type":414,"tag":558,"props":6221,"children":6222},{"style":6058},[6223],{"type":419,"value":6224},"    azurePowerShellVersion",{"type":414,"tag":558,"props":6226,"children":6227},{"style":670},[6228],{"type":419,"value":6066},{"type":414,"tag":558,"props":6230,"children":6231},{"style":670},[6232],{"type":419,"value":2420},{"type":414,"tag":558,"props":6234,"children":6235},{"style":696},[6236],{"type":419,"value":6237},"LatestVersion",{"type":414,"tag":558,"props":6239,"children":6240},{"style":670},[6241],{"type":419,"value":4133},{"type":414,"tag":415,"props":6243,"children":6244},{},[6245,6247,6252,6254,6261],{"type":419,"value":6246},"The advantage is that this task will connect to Azure with an Azure Service Connection that has enough rights to execute the Azure AD commands in this script. However, it involves passing to the ",{"type":414,"tag":554,"props":6248,"children":6250},{"className":6249},[],[6251],{"type":419,"value":2886},{"type":419,"value":6253}," command the access token of the Service Principal associated with the Azure Service Connection. This can easily be done as I found out in ",{"type":414,"tag":460,"props":6255,"children":6258},{"href":6256,"rel":6257},"https://stackoverflow.com/questions/60185213/automate-connect-azuread-using-powershell-in-azure-devops",[464],[6259],{"type":419,"value":6260},"a StackOverflow post",{"type":419,"value":597},{"type":414,"tag":548,"props":6263,"children":6265},{"className":644,"code":6264,"language":248,"meta":401,"style":401},"$context = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile.DefaultContext\n$graphToken = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate($context.Account, $context.Environment, $context.Tenant.Id.ToString(), $null, [Microsoft.Azure.Commands.Common.Authentication.ShowDialog]::Never, $null, \"https://graph.microsoft.com\").AccessToken\n$aadToken = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate($context.Account, $context.Environment, $context.Tenant.Id.ToString(), $null, [Microsoft.Azure.Commands.Common.Authentication.ShowDialog]::Never, $null, \"https://graph.windows.net\").AccessToken\nConnect-AzureAD -AadAccessToken $aadToken -MsAccessToken $graphToken -AccountId $context.Account.Id -TenantId $context.tenant.id\n",[6266],{"type":414,"tag":554,"props":6267,"children":6268},{"__ignoreMap":401},[6269,6304,6432,6549],{"type":414,"tag":558,"props":6270,"children":6271},{"class":560,"line":561},[6272,6276,6281,6285,6290,6295,6299],{"type":414,"tag":558,"props":6273,"children":6274},{"style":670},[6275],{"type":419,"value":1514},{"type":414,"tag":558,"props":6277,"children":6278},{"style":565},[6279],{"type":419,"value":6280},"context ",{"type":414,"tag":558,"props":6282,"children":6283},{"style":670},[6284],{"type":419,"value":2310},{"type":414,"tag":558,"props":6286,"children":6287},{"style":670},[6288],{"type":419,"value":6289}," [",{"type":414,"tag":558,"props":6291,"children":6292},{"style":1444},[6293],{"type":419,"value":6294},"Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider",{"type":414,"tag":558,"props":6296,"children":6297},{"style":670},[6298],{"type":419,"value":3684},{"type":414,"tag":558,"props":6300,"children":6301},{"style":565},[6302],{"type":419,"value":6303},"::Instance.Profile.DefaultContext\n",{"type":414,"tag":558,"props":6305,"children":6306},{"class":560,"line":661},[6307,6311,6316,6320,6324,6329,6333,6338,6342,6347,6352,6356,6361,6365,6369,6374,6379,6384,6388,6393,6397,6402,6406,6410,6414,6419,6423,6427],{"type":414,"tag":558,"props":6308,"children":6309},{"style":670},[6310],{"type":419,"value":1514},{"type":414,"tag":558,"props":6312,"children":6313},{"style":565},[6314],{"type":419,"value":6315},"graphToken ",{"type":414,"tag":558,"props":6317,"children":6318},{"style":670},[6319],{"type":419,"value":2310},{"type":414,"tag":558,"props":6321,"children":6322},{"style":670},[6323],{"type":419,"value":6289},{"type":414,"tag":558,"props":6325,"children":6326},{"style":1444},[6327],{"type":419,"value":6328},"Microsoft.Azure.Commands.Common.Authentication.AzureSession",{"type":414,"tag":558,"props":6330,"children":6331},{"style":670},[6332],{"type":419,"value":3684},{"type":414,"tag":558,"props":6334,"children":6335},{"style":565},[6336],{"type":419,"value":6337},"::Instance.AuthenticationFactory.Authenticate",{"type":414,"tag":558,"props":6339,"children":6340},{"style":670},[6341],{"type":419,"value":3327},{"type":414,"tag":558,"props":6343,"children":6344},{"style":565},[6345],{"type":419,"value":6346},"context.Account",{"type":414,"tag":558,"props":6348,"children":6349},{"style":670},[6350],{"type":419,"value":6351},",",{"type":414,"tag":558,"props":6353,"children":6354},{"style":670},[6355],{"type":419,"value":1535},{"type":414,"tag":558,"props":6357,"children":6358},{"style":565},[6359],{"type":419,"value":6360},"context.Environment",{"type":414,"tag":558,"props":6362,"children":6363},{"style":670},[6364],{"type":419,"value":6351},{"type":414,"tag":558,"props":6366,"children":6367},{"style":670},[6368],{"type":419,"value":1535},{"type":414,"tag":558,"props":6370,"children":6371},{"style":565},[6372],{"type":419,"value":6373},"context.Tenant.Id.ToString",{"type":414,"tag":558,"props":6375,"children":6376},{"style":670},[6377],{"type":419,"value":6378},"(),",{"type":414,"tag":558,"props":6380,"children":6381},{"style":670},[6382],{"type":419,"value":6383}," $null,",{"type":414,"tag":558,"props":6385,"children":6386},{"style":670},[6387],{"type":419,"value":6289},{"type":414,"tag":558,"props":6389,"children":6390},{"style":1444},[6391],{"type":419,"value":6392},"Microsoft.Azure.Commands.Common.Authentication.ShowDialog",{"type":414,"tag":558,"props":6394,"children":6395},{"style":670},[6396],{"type":419,"value":3684},{"type":414,"tag":558,"props":6398,"children":6399},{"style":565},[6400],{"type":419,"value":6401},"::Never",{"type":414,"tag":558,"props":6403,"children":6404},{"style":670},[6405],{"type":419,"value":6351},{"type":414,"tag":558,"props":6407,"children":6408},{"style":670},[6409],{"type":419,"value":6383},{"type":414,"tag":558,"props":6411,"children":6412},{"style":670},[6413],{"type":419,"value":1504},{"type":414,"tag":558,"props":6415,"children":6416},{"style":696},[6417],{"type":419,"value":6418},"https://graph.microsoft.com",{"type":414,"tag":558,"props":6420,"children":6421},{"style":670},[6422],{"type":419,"value":693},{"type":414,"tag":558,"props":6424,"children":6425},{"style":670},[6426],{"type":419,"value":3337},{"type":414,"tag":558,"props":6428,"children":6429},{"style":565},[6430],{"type":419,"value":6431},".AccessToken\n",{"type":414,"tag":558,"props":6433,"children":6434},{"class":560,"line":707},[6435,6439,6444,6448,6452,6456,6460,6464,6468,6472,6476,6480,6484,6488,6492,6496,6500,6504,6508,6512,6516,6520,6524,6528,6532,6537,6541,6545],{"type":414,"tag":558,"props":6436,"children":6437},{"style":670},[6438],{"type":419,"value":1514},{"type":414,"tag":558,"props":6440,"children":6441},{"style":565},[6442],{"type":419,"value":6443},"aadToken ",{"type":414,"tag":558,"props":6445,"children":6446},{"style":670},[6447],{"type":419,"value":2310},{"type":414,"tag":558,"props":6449,"children":6450},{"style":670},[6451],{"type":419,"value":6289},{"type":414,"tag":558,"props":6453,"children":6454},{"style":1444},[6455],{"type":419,"value":6328},{"type":414,"tag":558,"props":6457,"children":6458},{"style":670},[6459],{"type":419,"value":3684},{"type":414,"tag":558,"props":6461,"children":6462},{"style":565},[6463],{"type":419,"value":6337},{"type":414,"tag":558,"props":6465,"children":6466},{"style":670},[6467],{"type":419,"value":3327},{"type":414,"tag":558,"props":6469,"children":6470},{"style":565},[6471],{"type":419,"value":6346},{"type":414,"tag":558,"props":6473,"children":6474},{"style":670},[6475],{"type":419,"value":6351},{"type":414,"tag":558,"props":6477,"children":6478},{"style":670},[6479],{"type":419,"value":1535},{"type":414,"tag":558,"props":6481,"children":6482},{"style":565},[6483],{"type":419,"value":6360},{"type":414,"tag":558,"props":6485,"children":6486},{"style":670},[6487],{"type":419,"value":6351},{"type":414,"tag":558,"props":6489,"children":6490},{"style":670},[6491],{"type":419,"value":1535},{"type":414,"tag":558,"props":6493,"children":6494},{"style":565},[6495],{"type":419,"value":6373},{"type":414,"tag":558,"props":6497,"children":6498},{"style":670},[6499],{"type":419,"value":6378},{"type":414,"tag":558,"props":6501,"children":6502},{"style":670},[6503],{"type":419,"value":6383},{"type":414,"tag":558,"props":6505,"children":6506},{"style":670},[6507],{"type":419,"value":6289},{"type":414,"tag":558,"props":6509,"children":6510},{"style":1444},[6511],{"type":419,"value":6392},{"type":414,"tag":558,"props":6513,"children":6514},{"style":670},[6515],{"type":419,"value":3684},{"type":414,"tag":558,"props":6517,"children":6518},{"style":565},[6519],{"type":419,"value":6401},{"type":414,"tag":558,"props":6521,"children":6522},{"style":670},[6523],{"type":419,"value":6351},{"type":414,"tag":558,"props":6525,"children":6526},{"style":670},[6527],{"type":419,"value":6383},{"type":414,"tag":558,"props":6529,"children":6530},{"style":670},[6531],{"type":419,"value":1504},{"type":414,"tag":558,"props":6533,"children":6534},{"style":696},[6535],{"type":419,"value":6536},"https://graph.windows.net",{"type":414,"tag":558,"props":6538,"children":6539},{"style":670},[6540],{"type":419,"value":693},{"type":414,"tag":558,"props":6542,"children":6543},{"style":670},[6544],{"type":419,"value":3337},{"type":414,"tag":558,"props":6546,"children":6547},{"style":565},[6548],{"type":419,"value":6431},{"type":414,"tag":558,"props":6550,"children":6551},{"class":560,"line":716},[6552,6556,6560,6565,6569,6573,6577,6582,6586,6590,6594,6599,6603,6608,6612,6616,6620],{"type":414,"tag":558,"props":6553,"children":6554},{"style":730},[6555],{"type":419,"value":2886},{"type":414,"tag":558,"props":6557,"children":6558},{"style":670},[6559],{"type":419,"value":1572},{"type":414,"tag":558,"props":6561,"children":6562},{"style":565},[6563],{"type":419,"value":6564},"AadAccessToken ",{"type":414,"tag":558,"props":6566,"children":6567},{"style":670},[6568],{"type":419,"value":1514},{"type":414,"tag":558,"props":6570,"children":6571},{"style":565},[6572],{"type":419,"value":6443},{"type":414,"tag":558,"props":6574,"children":6575},{"style":670},[6576],{"type":419,"value":673},{"type":414,"tag":558,"props":6578,"children":6579},{"style":565},[6580],{"type":419,"value":6581},"MsAccessToken ",{"type":414,"tag":558,"props":6583,"children":6584},{"style":670},[6585],{"type":419,"value":1514},{"type":414,"tag":558,"props":6587,"children":6588},{"style":565},[6589],{"type":419,"value":6315},{"type":414,"tag":558,"props":6591,"children":6592},{"style":670},[6593],{"type":419,"value":673},{"type":414,"tag":558,"props":6595,"children":6596},{"style":565},[6597],{"type":419,"value":6598},"AccountId ",{"type":414,"tag":558,"props":6600,"children":6601},{"style":670},[6602],{"type":419,"value":1514},{"type":414,"tag":558,"props":6604,"children":6605},{"style":565},[6606],{"type":419,"value":6607},"context.Account.Id ",{"type":414,"tag":558,"props":6609,"children":6610},{"style":670},[6611],{"type":419,"value":673},{"type":414,"tag":558,"props":6613,"children":6614},{"style":565},[6615],{"type":419,"value":2895},{"type":414,"tag":558,"props":6617,"children":6618},{"style":670},[6619],{"type":419,"value":1514},{"type":414,"tag":558,"props":6621,"children":6622},{"style":565},[6623],{"type":419,"value":6624},"context.tenant.id\n",{"type":414,"tag":791,"props":6626,"children":6628},{"id":6627},"summary",[6629],{"type":419,"value":6630},"Summary",{"type":414,"tag":415,"props":6632,"children":6633},{},[6634,6636,6641],{"type":419,"value":6635},"In this post, I wanted to show the different steps to configure Teams Tab SSO in PowerShell. The final script can be found ",{"type":414,"tag":460,"props":6637,"children":6639},{"href":2633,"rel":6638},[464],[6640],{"type":419,"value":838},{"type":419,"value":6642}," and is directly used in an Azure pipeline to automate this configuration. Although it does the job, I hope doing such Azure AD configurations will be supported soon in Pulumi as it would have been easier to set it up instead of coming up with a big PowerShell script like this which is not idempotent.",{"type":414,"tag":1957,"props":6644,"children":6645},{},[6646],{"type":419,"value":1961},{"title":401,"searchDepth":661,"depth":661,"links":6648},[6649,6650,6659],{"id":423,"depth":661,"text":426},{"id":2672,"depth":661,"text":2675,"children":6651},[6652,6653,6654,6655,6656,6657,6658],{"id":2706,"depth":707,"text":2709},{"id":2912,"depth":707,"text":2915},{"id":3014,"depth":707,"text":3017},{"id":3089,"depth":707,"text":3092},{"id":3209,"depth":707,"text":3212},{"id":4076,"depth":707,"text":4079},{"id":4676,"depth":707,"text":4679},{"id":6018,"depth":661,"text":6021,"children":6660},[6661],{"id":6627,"depth":707,"text":6630},"content:1.posts:7.teams-sso-powershell.md","1.posts/7.teams-sso-powershell.md",1716749600687]