<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.0">Jekyll</generator><link href="https://millerb.co.uk/feed.xml" rel="self" type="application/atom+xml" /><link href="https://millerb.co.uk/" rel="alternate" type="text/html" /><updated>2022-03-19T08:57:27+00:00</updated><id>https://millerb.co.uk/feed.xml</id><title type="html">Brett Miller</title><subtitle>Cloud Platform Engineer&lt;/br&gt; Microsoft MVP&lt;/br&gt;</subtitle><author><name>Brett Miller</name></author><entry><title type="html">Making Sense of Azure Functions Routes</title><link href="https://millerb.co.uk/2022/03/15/azure-functions-route-prefix.html" rel="alternate" type="text/html" title="Making Sense of Azure Functions Routes" /><published>2022-03-15T00:00:00+00:00</published><updated>2022-03-15T00:00:00+00:00</updated><id>https://millerb.co.uk/2022/03/15/azure-functions-route-prefix</id><content type="html" xml:base="https://millerb.co.uk/2022/03/15/azure-functions-route-prefix.html">&lt;p&gt;When you initialise a new HTTP trigger function using the Azure Functions CLI, you are prompted for the name for your function. This name is used for the folder within your project but also the name of the function itself. There are also some default configuration settings for the URI that will be used when you publish your FunctionApp.&lt;/p&gt;

&lt;h3 id=&quot;route-prefixes&quot;&gt;Route Prefixes&lt;/h3&gt;
&lt;p&gt;When you create Azure Functions project which has HTTP endpoints all function routes by default are prefixed with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;api&lt;/code&gt; e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;myFunctionProject/api/&amp;lt;functionName&amp;gt;&lt;/code&gt;. This is fine for most cases, but it can be confusing as it is not very descriptive.&lt;/p&gt;

&lt;p&gt;You can however customise this URI route within your Azure Functions project so that it can be more useful.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h3 id=&quot;changing-the-route-prefix&quot;&gt;Changing the Route Prefix&lt;/h3&gt;

&lt;p&gt;Within your PowerShell Azure Functions project you have a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;host.json&lt;/code&gt; file which contains the settings for your Functions project.&lt;/p&gt;

&lt;p&gt;Full docs on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;host.json&lt;/code&gt; file can be found here: &lt;a href=&quot;https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference-host-json&quot;&gt;host.json reference for Azure Functions 2.x and later&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can customize or remove the prefix using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;extensions.http.routePrefix&lt;/code&gt; property in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;host.json&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Below is an example of how to remove the route prefix from your functions by setting the routePrefix property to an empty string:&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;extensions&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;http&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;routePrefix&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Given that there is no real need to have a pre-defined route prefix I tend to do this on most of my projects to make the URI’s easier to read and distinguish from each other, especially when there are multiple functions within the project.&lt;/p&gt;

&lt;h3 id=&quot;changing-the-route-of-your-functions&quot;&gt;Changing the Route of your Functions&lt;/h3&gt;

&lt;p&gt;Now that you have removed the routePrefix from your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;host.json&lt;/code&gt; file, you also have the option to customise your functions route on a per function basis.&lt;/p&gt;

&lt;p&gt;Below is an example of how to change the route for a specific function by setting the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;route&lt;/code&gt; property in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;function.json&lt;/code&gt; file:&lt;/p&gt;
&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;bindings&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;authLevel&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;function&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;httpTrigger&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;direction&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;in&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Request&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;methods&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;get&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;post&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;route&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;descriptiveFunctionName&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;http&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;direction&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;out&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Response&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This allows you greater control over the URI for your function and makes it more descriptive.&lt;/p&gt;

&lt;p&gt;If I start a local debug of a basic HTTP function you can see the changes you have made to the route prefix and function route:&lt;/p&gt;

&lt;h4 id=&quot;before&quot;&gt;Before:&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/routePrefixAfter.png&quot; alt=&quot;RoutePrefixBefore&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;after&quot;&gt;After:&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/routePrefixBefore.png&quot; alt=&quot;RoutePrefixAfter&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;why-does-it-really-matter&quot;&gt;Why does it really matter?!&lt;/h3&gt;

&lt;p&gt;In this contrived example there’s no real need to change the route prefix or the function route but if you have a project which has multiple functions with similar names you may want to change the route to group specific functions together.&lt;/p&gt;

&lt;p&gt;For example you could have multiple functions within your project and you want to define the route to coincide with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;METHOD&lt;/code&gt; of the HTTP request for each function.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2022-03-18-15-50-34.png&quot; alt=&quot;Elaborate Example of multiple HTTP Endpoints&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;This blog post shows you some of the basic changes you can make to the route prefix and function route within your Azure Functions project.&lt;/p&gt;

&lt;p&gt;There are some other cool things that you can do with routes within your functions projects which I will cover in a follow up post soon.&lt;/p&gt;</content><author><name>Brett Miller</name></author><category term="Azure Functions" /><category term="PowerShell" /><category term="Azure" /><summary type="html">When you initialise a new HTTP trigger function using the Azure Functions CLI, you are prompted for the name for your function. This name is used for the folder within your project but also the name of the function itself. There are also some default configuration settings for the URI that will be used when you publish your FunctionApp. Route Prefixes When you create Azure Functions project which has HTTP endpoints all function routes by default are prefixed with api e.g. myFunctionProject/api/&amp;lt;functionName&amp;gt;. This is fine for most cases, but it can be confusing as it is not very descriptive. You can however customise this URI route within your Azure Functions project so that it can be more useful.</summary></entry><entry><title type="html">Multiple GitHub Account Management</title><link href="https://millerb.co.uk/2022/02/21/multiple-git-accounts.html" rel="alternate" type="text/html" title="Multiple GitHub Account Management" /><published>2022-02-21T00:00:00+00:00</published><updated>2022-02-21T00:00:00+00:00</updated><id>https://millerb.co.uk/2022/02/21/multiple-git-accounts</id><content type="html" xml:base="https://millerb.co.uk/2022/02/21/multiple-git-accounts.html">&lt;p&gt;If you have multiple github accounts then you will very quickly become aware of an annoyance of having to manage your git config for each repository. If you don’t want to commit as the account configured in your global &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.gitconfig&lt;/code&gt; then you have to remember to set your username and email on each repository that you clone or create.&lt;/p&gt;

&lt;p&gt;If you don’t become aware of this then you will quickly be searching StackOverflow for how to amend the last commit author.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h3 id=&quot;use-a-personal-gitconfig&quot;&gt;Use a personal gitconfig&lt;/h3&gt;
&lt;p&gt;The way I have been managing this is by using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;includeIf&lt;/code&gt; section within my &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.gitconfig&lt;/code&gt; file and if the path of the repository is in my personal projects directory to include an alternative gitconfig.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# If Path is personal projects then use personal gitconfig&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# The /i makes the path case insensitive&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;includeIf &lt;span class=&quot;s2&quot;&gt;&quot;gitdir/i:C://git/personal/&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
	path &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; ~/.gitconfig-personal
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This tells git that if you’re directory is in the path defined in gitdir then to use the .gitconfig-personal file instead of the usual config file.&lt;/p&gt;

&lt;p&gt;In your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.gitconfig-personal&lt;/code&gt; folder add your personal details.&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;user]
    name &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; Brett Miller
    email &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; brett@millerb.co.uk
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;the-downside&quot;&gt;The Downside&lt;/h3&gt;
&lt;p&gt;Using this method does not work so well if, like me, you use different SSH keys for accessing the two accounts then you also need to use an ssh config and when you clone a repository you have to change the URL e.g. when I clone a personal repository I have to change the remote URL to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;personal.github.com&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;❯❯ &lt;span class=&quot;nb&quot;&gt;cat&lt;/span&gt; ~/.ssh/config

&lt;span class=&quot;c&quot;&gt;# Github Personal account&lt;/span&gt;
  Host personal.github.com
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_rsa_personal

&lt;span class=&quot;c&quot;&gt;# Github Work account&lt;/span&gt;
  Host github.com
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_rsa_work
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;an-even-easier-way&quot;&gt;An Even Easier Way&lt;/h3&gt;
&lt;p&gt;So I stumbled upon a blog post a little while ago which showed an easier way to do this resulting in no longer requiring a different gitconfig for personal configuration. I have just changed workstations so decided that I would configure this properly.&lt;/p&gt;

&lt;p&gt;After searching for about an hour for the blog post I finally &lt;a href=&quot;https://dev.to/arnellebalane/setting-up-multiple-github-accounts-the-nicer-way-1m5m&quot;&gt;found it&lt;/a&gt; or at least something that covered what I was looking for).&lt;/p&gt;

&lt;p&gt;This uses the same &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;includeIf&lt;/code&gt; that I was using before but makes it even easier!&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;❯ &lt;span class=&quot;nb&quot;&gt;cat&lt;/span&gt; ~/.gitconfig
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;user]
    name &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; Brett Miller
    email &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; brett.miller@work.com

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;core]
    sshCommand &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;ssh -i ~/.ssh/id_rsa_work&quot;&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;init]
    defaultBranch &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; main

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;includeIf &lt;span class=&quot;s2&quot;&gt;&quot;gitdir/i:C:/git/personal/&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;user]
        email &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; brett.miller@millerb.co.uk

    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;core]
        sshCommand &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;ssh -i ~/.ssh/id_personal&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This uses the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;core.sshCommand&lt;/code&gt; setting to specify my personal SSH key if I am within a git project in my personal directory.&lt;/p&gt;

&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;/h3&gt;
&lt;p&gt;I used to use SSH authentication for work and HTTPS for personal projects. When I changed laptops a while ago I switched to SSH for both accounts. Now that GitHub have deprecated the use of basic authentication for HTTPS auth, it makes SSH more appealing&lt;/p&gt;

&lt;p&gt;Really pleased with this configuration as it has eliminated the need for an ssh config, a secondary gitconfig, I no longer have to change the remote repository URL or set user and email per repostory.&lt;/p&gt;

&lt;p&gt;Now to figure out GPG signing on a per account basis 🙌&lt;/p&gt;</content><author><name>Brett Miller</name></author><category term="git" /><category term="GitHub" /><category term="Productivity" /><summary type="html">If you have multiple github accounts then you will very quickly become aware of an annoyance of having to manage your git config for each repository. If you don’t want to commit as the account configured in your global .gitconfig then you have to remember to set your username and email on each repository that you clone or create. If you don’t become aware of this then you will quickly be searching StackOverflow for how to amend the last commit author.</summary></entry><entry><title type="html">Secret Santa Generator</title><link href="https://millerb.co.uk/2021/11/25/Secret-Santa-Generator.html" rel="alternate" type="text/html" title="Secret Santa Generator" /><published>2021-11-25T00:00:00+00:00</published><updated>2021-11-25T00:00:00+00:00</updated><id>https://millerb.co.uk/2021/11/25/Secret-Santa-Generator</id><content type="html" xml:base="https://millerb.co.uk/2021/11/25/Secret-Santa-Generator.html">&lt;p&gt;This year I was designated to organise secret santa for the family 🎅&lt;/p&gt;

&lt;p&gt;Naturally I opted to be a total nerd about it and use PowerShell to randomly generate who would be gifting presents.&lt;/p&gt;

&lt;h3 id=&quot;ho-ho-ho&quot;&gt;Ho Ho Ho&lt;/h3&gt;
&lt;p&gt;I started out knowing the list of people taking part, even if they didn’t know they were participating at the time and I would just randomly assign them someone to buy a present for……simple right?!&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/24279339/143514112-9c1ce449-4b7d-4f12-8498-af2c163eb493.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;define-a-list-of-names&quot;&gt;Define a list of names&lt;/h3&gt;
&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Names changed to protect the innocent&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$names&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@(&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Jeff'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Maria'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Veronica'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Wolfgang'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Francisco'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Persephone'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Meryl'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Jerry'&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Loop over the names and assign a santa and who they are buying for&lt;/p&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kr&quot;&gt;foreach&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$person&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$names&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# Looping through the list of names and make sure a person can't be their own secret santa&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$buyingFor&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$names&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Where-Object&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-ne&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$person&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Get-Random&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Count&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    
    &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# Print out the name of the person and the name of the person they are buying for&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'{0} is buying for {1}'&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$buyingFor&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# Remove the person from the list so they can't be chosen again&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$names&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$names&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Where-Object&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-ne&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$buyingFor&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The downside to this is that every now and then there was an issue with the last person in the loop would sometimes not have anyone to buy for. I wonder if I could fix it so that I was last in the list 🤔&lt;/p&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;Jeff&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;is&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;buying&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Wolfgang&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Maria&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;is&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;buying&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Francisco&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Veronica&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;is&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;buying&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Persephone&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Wolfgang&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;is&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;buying&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Meryl&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Francisco&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;is&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;buying&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Maria&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Persephone&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;is&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;buying&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Jeff&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Meryl&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;is&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;buying&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Veronica&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Jerry&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;is&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;buying&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;🙃&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;to-google&quot;&gt;To Google&lt;/h3&gt;
&lt;p&gt;This wasn’t as easy as my ‘Quick PowerShell script’ idea initially planned so naturally I did what any engineer would do!&lt;/p&gt;

&lt;p&gt;I googled &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;powershell secret santa&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The first result was from Mike F. Robbins (&lt;a href=&quot;https://twitter.com/mikefrobbins&quot;&gt;@mikefrobbins&lt;/a&gt;) naturally and it looked perfect for what I was trying to do.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mike’s blog post:&lt;/strong&gt; &lt;a href=&quot;https://mikefrobbins.com/2017/12/21/generate-a-secret-santa-list-with-powershell/&quot;&gt;https://mikefrobbins.com/2017/12/21/generate-a-secret-santa-list-with-powershell/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Interestingly he encountered the same issue I did with the basic loop sometimes leaving a santa without someone to gift a present to. I decided to steal Mike’s code to make my life easier.&lt;/p&gt;

&lt;h3 id=&quot;mikes-secret-santa-function&quot;&gt;Mike’s Secret Santa Function&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;I’ve removed the comment based help for brevity.&lt;/em&gt;&lt;/p&gt;
&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kr&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Get-MrSecretSantaList&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CmdletBinding&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;param&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Parameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Mandatory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ValidateCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32768&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Name&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-ne&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;Throw&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'An even number of Names must be specified in order for matching to occur.'&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Giftee&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Name&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Sort-Object&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Get-Random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;while&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-lt&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-eq&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Giftee&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Write-Verbose&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Message&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;A duplicate has occured in loop &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; Name: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; cannot match Giftee: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Giftee&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;$true&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-lt&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pscustomobject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]@{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Gifter&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Giftee&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Giftee&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This works great but with only one problem! I am in the secret santa so I don’t want to know who other people are buying for, including me! So i will have to change it up a little.&lt;/p&gt;

&lt;h3 id=&quot;modified-solution&quot;&gt;Modified solution&lt;/h3&gt;

&lt;p&gt;The main changes are in the latter part of the function which generates the output. I don’t want to print to the screen and spoil the surprise so I decided I would write the results to a file so that I could send the file to people without opening it and revealing who the recipients of the gift were.&lt;/p&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kr&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Get-MrSecretSantaList&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CmdletBinding&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;param&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Parameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Mandatory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ValidateCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32768&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Name&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-ne&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;Throw&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'An even number of Names must be specified in order for matching to occur.'&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Giftee&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Name&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Sort-Object&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Get-Random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;while&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-lt&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-eq&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Giftee&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Write-Verbose&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Message&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;A duplicate has occured in loop &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; Name: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; cannot match Giftee: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Giftee&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;$true&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-lt&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# Create a file name of the Secret Santa&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$fileName&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'{0}.txt'&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    
        &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# Generate a file name of the Secret Santa with the persons name.&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# GetUnresolvedProviderPathFromPsPath will add the files to the $PWD&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$outputPath&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Join-Path&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Path&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;$PSCmdlet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetUnresolvedProviderPathFromPSPath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'.'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-ChildPath&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$fileName&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    
        &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# Add a line of text to tell Santa who they are gifting the present to.&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$fileValue&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Your buying for {0}'&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Giftee&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Set-Content&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Path&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$outputPath&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Value&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$fileValue&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;outcome&quot;&gt;Outcome&lt;/h3&gt;
&lt;p&gt;This was the quickest way I could think of that would generate a secret santa for everyone without me, the organiser, knowing who was gifting presents to whom. I then sent the individual files to each participant so that only they knew who they were gifting a present to.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/24279339/143514584-194e5f63-d7b6-4ac7-a83d-71d150b5ffb5.png&quot; alt=&quot;OutputFile&quot; /&gt;&lt;/p&gt;</content><author><name>Brett Miller</name></author><category term="PowerShell" /><category term="SecretSanta" /><summary type="html">This year I was designated to organise secret santa for the family 🎅 Naturally I opted to be a total nerd about it and use PowerShell to randomly generate who would be gifting presents. Ho Ho Ho I started out knowing the list of people taking part, even if they didn’t know they were participating at the time and I would just randomly assign them someone to buy a present for……simple right?!</summary></entry><entry><title type="html">Parsing Docker Output with jq</title><link href="https://millerb.co.uk/2021/11/23/docker-pwsh-jq.html" rel="alternate" type="text/html" title="Parsing Docker Output with jq" /><published>2021-11-23T00:00:00+00:00</published><updated>2021-11-23T00:00:00+00:00</updated><id>https://millerb.co.uk/2021/11/23/docker-pwsh-jq</id><content type="html" xml:base="https://millerb.co.uk/2021/11/23/docker-pwsh-jq.html">&lt;p&gt;There was a question that came up in the &lt;a href=&quot;https://aka.ms/psdiscord&quot;&gt;PowerShell discord&lt;/a&gt; last week which was an interesting question which ended up with 3 entirely different answers from different people which is interesting to see how different people approach a problem.&lt;/p&gt;

&lt;h3 id=&quot;goal&quot;&gt;Goal!&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;The goal is to get a list of images from docker images command and delete them with docker rmi
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;!--more--&gt;

&lt;h3 id=&quot;more-than-one-way-to-cook-an-egg&quot;&gt;More than one way to cook an egg&lt;/h3&gt;
&lt;p&gt;Shane O’Neill (&lt;a href=&quot;https://twitter.com/SOZDBA/&quot;&gt;@Shaneis&lt;/a&gt;) went for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-split&lt;/code&gt; operator and some regex to obtain the Name&lt;/p&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;❯❯&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$d&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ps&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-a&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;❯❯&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$d&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ForEach-Object&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Process&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;     &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PSCustomObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]@{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;         &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'\s{2,}'&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;     &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;----&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ecstatic_chandrasekhar&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;modest_colden&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;confident_newton&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;charming_ganguly&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;infallible_bassi&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Jos Koelewijn &lt;a href=&quot;https://twitter.com/Jawz_84/&quot;&gt;(@jawz_84&lt;/a&gt;) resorted to using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ConvertFrom-StringData&lt;/code&gt; which converts string output into a hashtable so you can access the key/value pairs.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;❯❯ docker images | Select-Object -Skip 1 | ConvertFrom-StringData -Delimiter ' ' | ForEach-Object Keys
vsc-socialopinions-d9e1feb0b3c073836b87b223deef5934
vsc-azureadfunction-fddb75b17c14d953fe380384c6a1553f
vsc-hacktoberfestscot-e2763e33d037a0d4346af8af7577007a
vsc-stucco-6fc12c4e758f0f1744dacf9375502cd2
vsc-stuccotest-17e1b8eb5a6cf01465f888a61c8384fa
vsc-stuccofix-5998915b92e138a5f4d7cd7c3d3af669
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;my-powershell-comfort-blanket-&quot;&gt;My PowerShell comfort blanket 🛌&lt;/h3&gt;

&lt;p&gt;PowerShell makes it so easy to perform data manipulation that you very rarely have to use anything else.&lt;/p&gt;

&lt;p&gt;I knew that docker had JSON output so I just had the command output the format and use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ConvertFrom-Json&lt;/code&gt;. Using jq and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--slurp&lt;/code&gt; formats individual JSON objects into a large array.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker container &lt;span class=&quot;nb&quot;&gt;ls&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--all&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--format&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'{{json .}}'&lt;/span&gt; | jq &lt;span class=&quot;nt&quot;&gt;--slurp&lt;/span&gt; | ConvertFrom-Json | Select-Object &lt;span class=&quot;nt&quot;&gt;-Property&lt;/span&gt; names
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;What about a bit further outside of my comfort zone and not relying on PowerShell? Docker allows you to provide a filter for your format to only return specific properties.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker container &lt;span class=&quot;nb&quot;&gt;ls&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--all&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--format&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'{{.Names}}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;and-what-about-using-just-jq&quot;&gt;And what about using &lt;em&gt;just&lt;/em&gt; jq?&lt;/h3&gt;
&lt;p&gt;You can use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.[]&lt;/code&gt; object iterator to return only the properties you want.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker container &lt;span class=&quot;nb&quot;&gt;ls&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--all&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--format&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'{{json .}}'&lt;/span&gt; | jq &lt;span class=&quot;s1&quot;&gt;'.Names'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Or again using slurp and only selecting the property you require.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker container &lt;span class=&quot;nb&quot;&gt;ls&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--all&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--format&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'{{json .}}'&lt;/span&gt; | jq &lt;span class=&quot;nt&quot;&gt;--slurp&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'.[] | .Names'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;There are many ways to achieve the same thing and people will generally tackle a problem in the way they’re most comfortable with.&lt;/p&gt;

&lt;p&gt;I’ve found over the years that having small amounts of familiarity with different tool sets outside of my normal wheelhouse is beneficial for those moments that you may not have your normal toolset available to you.&lt;/p&gt;

&lt;p&gt;Whilst I may have skirted around the goal of removing the containers once you are able to parse the output it can be utilised however you see fit.&lt;/p&gt;</content><author><name>Brett Miller</name></author><category term="powershell" /><category term="json" /><category term="jq" /><summary type="html">There was a question that came up in the PowerShell discord last week which was an interesting question which ended up with 3 entirely different answers from different people which is interesting to see how different people approach a problem. Goal! The goal is to get a list of images from docker images command and delete them with docker rmi</summary></entry><entry><title type="html">git add –patch - Selectively track changes within a file</title><link href="https://millerb.co.uk/2021/11/16/git-add-patch.html" rel="alternate" type="text/html" title="git add –patch - Selectively track changes within a file" /><published>2021-11-16T00:00:00+00:00</published><updated>2021-11-16T00:00:00+00:00</updated><id>https://millerb.co.uk/2021/11/16/git-add-patch</id><content type="html" xml:base="https://millerb.co.uk/2021/11/16/git-add-patch.html">&lt;p&gt;If there is one thing I have learned whilst using git is that you never really stop learning git!&lt;/p&gt;

&lt;h3 id=&quot;scenario&quot;&gt;Scenario&lt;/h3&gt;
&lt;p&gt;I am working on fixing something in a project and whilst doing so I notice something else which needs to be fixed. Now I could go and raise an issue against the repo to remind myself that it needs to be fixed, alternatively I could add a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TODO&lt;/code&gt; in the code and there are extensions which track that for you.&lt;/p&gt;

&lt;p&gt;Or if you’re really clever you can fix it straight away and utilise git to selectively track changes within the file.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h3 id=&quot;git-add&quot;&gt;git add&lt;/h3&gt;
&lt;p&gt;Normally working on a change within a project, you will make and save the changes in your file then using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git add&lt;/code&gt; you will add the changes you just made to your index.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Add all local changes to your index&lt;/span&gt;
git add &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;

git commit &lt;span class=&quot;nt&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Made a super awesome change&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can be more selective than this by only commiting certain files so you can chunk changes across multiple files into different commits.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Only add changes to a specific file to your index&lt;/span&gt;
git add MyProject/subFolder/file.ps1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;git-add-patch&quot;&gt;git add –patch&lt;/h3&gt;
&lt;p&gt;You can go one step further utilising &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git add --patch&lt;/code&gt; which allows you to add specific changes within the same file to different commits.&lt;/p&gt;

&lt;p&gt;Using this blog post for example.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;❯❯ git status &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt;
On branch master
Your branch is up to &lt;span class=&quot;nb&quot;&gt;date &lt;/span&gt;with &lt;span class=&quot;s1&quot;&gt;'origin/master'&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;

Untracked files:
  &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;use &lt;span class=&quot;s2&quot;&gt;&quot;git add &amp;lt;file&amp;gt;...&quot;&lt;/span&gt; to include &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;what will be committed&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
	_posts/2021/11/2021-11-16-git-add-patch.md

nothing added to commit but untracked files present &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;use &lt;span class=&quot;s2&quot;&gt;&quot;git add&quot;&lt;/span&gt; to track&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I can choose to add different parts of the file to the index so that I can make my commits smaller and easier to track within the git history.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;❯❯ git add &lt;span class=&quot;nt&quot;&gt;--patch&lt;/span&gt; _posts/2021/11/2021-11-16-git-add-patch.md

@@ &lt;span class=&quot;nt&quot;&gt;-17&lt;/span&gt;,4 +17,6 @@

 &amp;lt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;--more--&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;

+### git add
+Normally working on a change within a project....etc

&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;1/3&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; Stage this hunk &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;y,n,q,a,d,j,J,g,/,e,?]?
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Git will show you a diff information about where the code is in the file, followed by the diff (hunk) of code that it has selectively chosen for you. This is followed by the number of hunks and some interactive options for adding code to the index.&lt;/p&gt;

&lt;p&gt;Typing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;?&lt;/code&gt; will show help for the interactive options. I’ve only listed the simple ones here:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;y - stage this hunk
n - &lt;span class=&quot;k&quot;&gt;do &lt;/span&gt;not stage this hunk
q - quit&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do &lt;/span&gt;not stage this hunk or any of the remaining ones
d - &lt;span class=&quot;k&quot;&gt;do &lt;/span&gt;not stage this hunk or any of the later hunks &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;the file
s - &lt;span class=&quot;nb&quot;&gt;split &lt;/span&gt;the current hunk into smaller hunks
? - print &lt;span class=&quot;nb&quot;&gt;help&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Once you have selected the hunks you want to add you will commit your changes with a relevant commit message&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;❯❯ git commit &lt;span class=&quot;nt&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Added first 2 hunks from patch&quot;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;gitAddPatch 4f998ba] Added first 2 hunks from patch
 1 file changed, 29 insertions&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;+&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
 create mode 100644 _posts/2021/11/2021-11-16-git-add-patch.md
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You’ll notice that running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git status&lt;/code&gt; again will still show the file still has untracked changes which is the remaining &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hunk&lt;/code&gt; that we didn’t add to the index.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;❯❯ git status
On branch gitAddPatch
Changes not staged &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;commit:
  &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;use &lt;span class=&quot;s2&quot;&gt;&quot;git add &amp;lt;file&amp;gt;...&quot;&lt;/span&gt; to update what will be committed&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;use &lt;span class=&quot;s2&quot;&gt;&quot;git restore &amp;lt;file&amp;gt;...&quot;&lt;/span&gt; to discard changes &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;working directory&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
	modified:   _posts/2021/11/2021-11-16-git-add-patch.md
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can then add the rest of the file to your index with a final &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git add .&lt;/code&gt; and a meaningful commit message.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; b23195b - &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;HEAD -&amp;gt; gitAddPatch&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; Added rest of changes to file &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;24 seconds ago&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &amp;lt;Brett Miller&amp;gt;
&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; 4f998ba - Added first 2 hunks from patch &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;3 minutes ago&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &amp;lt;Brett Miller&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Git as a utility is massive and I’ve definitely only scratched the surface of what it can do. Learning these little tips and tricks save me significant time and effort whilst working on projects.&lt;/p&gt;

&lt;p&gt;This came in handy recently when I had some parameters that I was changing during testing and I wanted to commit changes to the code but not the minor changes to the parameters that I was using for testing. I was able to fix another bug and patch the change to the file as a separate commit so that I could keep my git history clean and have it reviewed as a different pull request.&lt;/p&gt;</content><author><name>Brett Miller</name></author><category term="git" /><category term="productivity" /><summary type="html">If there is one thing I have learned whilst using git is that you never really stop learning git! Scenario I am working on fixing something in a project and whilst doing so I notice something else which needs to be fixed. Now I could go and raise an issue against the repo to remind myself that it needs to be fixed, alternatively I could add a TODO in the code and there are extensions which track that for you. Or if you’re really clever you can fix it straight away and utilise git to selectively track changes within the file.</summary></entry><entry><title type="html">Making The Switch to MacOS</title><link href="https://millerb.co.uk/2020/07/10/My-VSCode-Mac-Setup.html" rel="alternate" type="text/html" title="Making The Switch to MacOS" /><published>2020-07-10T00:00:00+00:00</published><updated>2020-07-10T00:00:00+00:00</updated><id>https://millerb.co.uk/2020/07/10/My-VSCode-Mac-Setup</id><content type="html" xml:base="https://millerb.co.uk/2020/07/10/My-VSCode-Mac-Setup.html">&lt;h3 class=&quot;no_toc&quot; id=&quot;warning---long-post-alertagain&quot;&gt;WARNING! - Long Post Alert…..Again.&lt;/h3&gt;

&lt;p&gt;I previously wrote a post on this which was very popular as I tried to document all of my productivity hacks and shortcuts that I use on a daily basis to assist in writing PowerShell. That post is &lt;a href=&quot;https://millerb.co.uk/2019/02/28/My-Vscode-Setup.html&quot;&gt;My VSCode Setup&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I have since moved from a Windows laptop to MacOS so I wanted to make a note of customisations and changes so I had a place to track all of them but other people may also find some of them handy.&lt;/p&gt;

&lt;p&gt;Some stuff won’t have changed too much because, well…..there was no need but my way of working has shifted slightly and I spend more time with a split terminal between bash and PowerShell.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;I thought the switch to MacOS was going to be more difficult than it initially was but once I sorted my muscle memory out (mainly for copy and paste) it was a pretty seamless transition. The multiple desktops and the trackpad/gestures is an awesome experience.&lt;/p&gt;

&lt;p&gt;Unfortunately I do have to keep an Azure VM handy for the &lt;strong&gt;very&lt;/strong&gt; odd ocassion that I may need something Windows specific.&lt;/p&gt;

&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#homebrew&quot; id=&quot;markdown-toc-homebrew&quot;&gt;Homebrew&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#terminal--lt-iterm2&quot; id=&quot;markdown-toc-terminal--lt-iterm2&quot;&gt;Terminal -lt iterm2&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#setting-zsh-as-the-default-shell&quot; id=&quot;markdown-toc-setting-zsh-as-the-default-shell&quot;&gt;Setting zsh as the default shell&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#customisationstweaks&quot; id=&quot;markdown-toc-customisationstweaks&quot;&gt;Customisations/Tweaks&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#make-the-dock-appear-faster-when-using-auto-hide&quot; id=&quot;markdown-toc-make-the-dock-appear-faster-when-using-auto-hide&quot;&gt;Make the dock appear faster when using auto hide&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#enable-case-insensitve-autocomplete&quot; id=&quot;markdown-toc-enable-case-insensitve-autocomplete&quot;&gt;Enable Case Insensitve Autocomplete&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#iterm2-keyboard-shortcuts&quot; id=&quot;markdown-toc-iterm2-keyboard-shortcuts&quot;&gt;iterm2 Keyboard Shortcuts&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#oh-my-zsh&quot; id=&quot;markdown-toc-oh-my-zsh&quot;&gt;Oh My Zsh&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#profile&quot; id=&quot;markdown-toc-profile&quot;&gt;Profile&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#bash--zshrc-profile&quot; id=&quot;markdown-toc-bash--zshrc-profile&quot;&gt;Bash / zshrc profile&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#powershell-profile&quot; id=&quot;markdown-toc-powershell-profile&quot;&gt;Powershell Profile&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#remote-development-extension&quot; id=&quot;markdown-toc-remote-development-extension&quot;&gt;Remote Development Extension&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#jq&quot; id=&quot;markdown-toc-jq&quot;&gt;JQ&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#other-things&quot; id=&quot;markdown-toc-other-things&quot;&gt;Other Things&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;homebrew&quot;&gt;Homebrew&lt;/h2&gt;
&lt;p&gt;Switching from Windows where I used Chocolatey for my software installation needs, I had heard about homebrew and was keen to make a start with using a decent package manager from the start.&lt;/p&gt;

&lt;p&gt;You can install homebrew from the command line too!&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/bin/bash &lt;span class=&quot;nt&quot;&gt;-c&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;curl &lt;span class=&quot;nt&quot;&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/Homebrew/install/master/install.sh&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now that you have Homebrew installed you can go about installing the rest of your applications.&lt;/p&gt;

&lt;p&gt;For reference:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;❯❯ brew list &lt;span class=&quot;nt&quot;&gt;-1&lt;/span&gt;                     ❯❯ brew cask list &lt;span class=&quot;nt&quot;&gt;-1&lt;/span&gt;
azure-cli                           azure-data-studio
gdbm                                discord
ncurses                             firefox
openssl                             insomnia
openssl@1.1                         iterm2
pcre                                keepassxc
python                              microsoft-azure-storage-explorer
python@3.8                          microsoft-edge-beta
readline                            microsoft-remote-desktop-beta
sqlite                              obs
xz                                  powershell-preview
zsh                                 sizeup
zsh-completions                     slack
                                    spotify
                                    spotmenu
                                    visual-studio-code-insiders
                                    zoomus
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;terminal--lt-iterm2&quot;&gt;Terminal -lt iterm2&lt;/h2&gt;
&lt;p&gt;So rather than use the standard built in terminal that comes pre-installed with MacOS I have opted to use iterm2 (mainly because I heard other people say that it was awesome and no other reason) and I love it.&lt;/p&gt;

&lt;p&gt;It supports pretty much anything you can throw at it in terms of fonts, customisations and themes.&lt;/p&gt;

&lt;h3 id=&quot;setting-zsh-as-the-default-shell&quot;&gt;Setting zsh as the default shell&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;chsh &lt;span class=&quot;nt&quot;&gt;-s&lt;/span&gt; /bin/zsh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;customisationstweaks&quot;&gt;Customisations/Tweaks&lt;/h2&gt;
&lt;p&gt;I seen a gist from &lt;a href=&quot;https://twitter.com/markwragg&quot;&gt;@markwragg&lt;/a&gt; which I bookmarked with the anticipation that I may one day switch to MacOS then unknowingly I made that switch my self. He documented some of the changes that he made when he switched to MacOS. That &lt;a href=&quot;https://gist.github.com/markwragg/d98645aa9ffb74623342cf09cf0c25e6&quot;&gt;gist is here&lt;/a&gt; and has some handy stuff within.&lt;/p&gt;

&lt;p&gt;I chose not to make as many changes as Mark but the ones I blatantly stole are:&lt;/p&gt;

&lt;h3 id=&quot;make-the-dock-appear-faster-when-using-auto-hide&quot;&gt;Make the dock appear faster when using auto hide&lt;/h3&gt;
&lt;p&gt;I have my notification bar and dock hidden on my mac for maximum screen real estate so this helps when quickly trying to access the dock.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;defaults write com.apple.dock autohide-delay &lt;span class=&quot;nt&quot;&gt;-float&lt;/span&gt; 0
killall dock
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;enable-case-insensitve-autocomplete&quot;&gt;Enable Case Insensitve Autocomplete&lt;/h3&gt;
&lt;p&gt;Case insensitive auto-complete is a total life saver coming from the windows world and I don’t know how many hours I have lost on linux machines debugging my own stupidity.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;echo &quot;set completion-ignore-case On&quot; &amp;gt;&amp;gt; ~/.inputrc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;iterm2-keyboard-shortcuts&quot;&gt;iterm2 Keyboard Shortcuts&lt;/h3&gt;
&lt;p&gt;Pressing ESC to clear the whole line in the terminal which is familiar behaviour for me and one of the muscle memory options that I want to keep. The rest of my keyboard shortcuts are listed below (that I can remember adding).&lt;/p&gt;

&lt;p&gt;iTerm2 &amp;gt; Preferences &amp;gt; Profiles &amp;gt; Keys&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Key Combination&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Action&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Wassat?&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;ESC&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;Send Hex Codes 0x15&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;Clears the current line&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;⌥ Backspace&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;Send Hex Codes: 0x17&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;BackwardKillWord&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;⌥ &amp;lt;-&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;Send Escape Sequence b&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;BackwardWord&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;⌥ -&amp;gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;Send Escape Sequence f&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;ForwardWord&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;⌥ Shift &amp;lt;-&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;Move Start of Selection Back -&amp;gt; Move by Word&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;Select BackwardWord&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;⌥ Shift -&amp;gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;Move End of Selection Forward -&amp;gt; Move by Word&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;Select ForwardWord&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;There are probably more but these are the ones I can remember adding.&lt;/p&gt;

&lt;h2 id=&quot;oh-my-zsh&quot;&gt;Oh My Zsh&lt;/h2&gt;
&lt;blockquote&gt;
  &lt;p&gt;Oh My Zsh is a delightful, open source, community-driven framework for managing your Zsh configuration. It comes bundled with thousands of helpful functions, helpers, plugins &amp;amp; themes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;profile&quot;&gt;Profile&lt;/h2&gt;
&lt;p&gt;This has changed slightly as I am now on MacOS in the fact that I am now running two different profiles for bash/zsh and one for PowerShell.&lt;/p&gt;

&lt;h3 id=&quot;bash--zshrc-profile&quot;&gt;Bash / zshrc profile&lt;/h3&gt;
&lt;p&gt;I am using PowerLevel9k for my theme which offers some nice customisations. I have not really played around with this beyond my initial setup which I am quite happy with.&lt;/p&gt;

&lt;p&gt;I am now finding that I am using zsh as a primary shell over PowerShell for day to day interaction especially when interacting with git. I also tend to stick to bash for Azure CLI too for the tab completion and speed it offers.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/24279339/91507315-6d1fe280-e8cc-11ea-9df9-cd2df562693b.png&quot; alt=&quot;iterm2 bash profile&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I have added this &lt;a href=&quot;https://gist.github.com/brettmillerb/5f9197ce3568b230f52c9641d92f99bb&quot;&gt;as a gist&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There are a few things that I have had to add to make my life easier when switching between bash/zsh and PowerShell so that I have consistent commands available to me.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cls&lt;/code&gt; is too engrained and quicker to type so that has to go in there. The other two aliases are pretty self-explanatory.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# aliases&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;alias &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'clear'&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;alias &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;code&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'code-insiders'&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;alias &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;pwsh&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'pwsh-preview'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The other thing that I really like is the tab completion for Azure CLI which doesn’t appear to work with zsh out of the box. Adding this to your zshrc profile enables that.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Azure CLI tab completion&lt;/span&gt;
autoload bashcompinit &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; bashcompinit
&lt;span class=&quot;nb&quot;&gt;source&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$ZSH&lt;/span&gt;/oh-my-zsh.sh
&lt;span class=&quot;nb&quot;&gt;source&lt;/span&gt; /usr/local/etc/bash_completion.d/az
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;powershell-profile&quot;&gt;Powershell Profile&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt; After a thread on twitter by &lt;a href=&quot;https://twitter.com/thedavecarroll/status/1295379473697832967?s=20&quot;&gt;Dave Carroll&lt;/a&gt; I decided to take a little time and fix up my pwsh profile to something a bit nicer.&lt;/p&gt;

&lt;p&gt;This has changed a little since I moved. Mainly to accommodate differences between bash and PowerShell on Mac so that they work in a consistent manner.&lt;/p&gt;

&lt;p&gt;My Toolbox module that I import in my profile can be found &lt;a href=&quot;https://github.com/brettmillerb/Toolbox&quot;&gt;here&lt;/a&gt; in my github repo. This has the following functions which are imported into my session.&lt;/p&gt;
&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Module with some helper functions&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Import-Module&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Name&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Toolbox&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;Backup-Profile.ps1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                 &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# Backs up my profile to github&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Export-AzKeyVaultCertificate.ps1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;   &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# Export Azure Key Vault PFX Certificate&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Get-CommandInfo.ps1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# Stolen from Chris Dent 😃&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Get-Gituser.ps1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                    &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# Shows the current folders git user from gitconfig&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Get-MultiPass.ps1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                  &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# Windows only CliXml Command to import Credentials object&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Get-Syntax.ps1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                     &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# Reformatting of Get-Command $Command -Syntax to print vertically&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;New-MultiPass.ps1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                  &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# Windows only CliXml Command to create Credenials object&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I like being able to traverse the directory structures quickly so these shortcuts allow me to jump back one or two directories quickly and are also available in zsh so it’s consistent behaviour across shells.&lt;/p&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# functions to be aliased to make traversing directories consistent with zsh shortcuts&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;BackOne&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Set-Location&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;BackTwo&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Set-Location&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;/..&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;zsh has some handy default parameters for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ls&lt;/code&gt; so I have added these to my PowerShell prompt as I am too used to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ls&lt;/code&gt; to stop using it so may as well make it consistent right?!&lt;/p&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kr&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Get-NativeChildItem&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Get-Command&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ls&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-CommandType&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Application&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-lhG&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Get-NativeChildItemG&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Get-Command&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ls&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-CommandType&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Application&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-G&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Get-NativeChildItemA&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Get-Command&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ls&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-CommandType&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Application&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-lAhG&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Alias all of the things&lt;/p&gt;
&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;New-Alias&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Name&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;code&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Value&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'code-insiders'&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;New-Alias&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Name&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'..'&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Value&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'BackOne'&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;New-Alias&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Name&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'...'&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Value&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'BackTwo'&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;New-Alias&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Name&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ll&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Value&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Get-NativeChildItem&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;New-Alias&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Name&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ls&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Value&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Get-NativeChildItemG&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;New-Alias&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Name&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;la&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Value&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Get-NativeChildItemA&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# clip on windows is clip.exe and I use this a lot.&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;New-Alias&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Name&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;clip&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Value&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Set-Clipboard&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;PSReadline is awesome and it’s made even more awesome on MacOS with the &lt;a href=&quot;https://www.powershellgallery.com/packages/Microsoft.PowerShell.UnixCompleters/0.1.1&quot;&gt;PSUnixUtilCompleters&lt;/a&gt; PowerShell module by &lt;a href=&quot;https://twitter.com/rjmholt&quot;&gt;@rjmholt&lt;/a&gt; which gives you parameter completers for native linux and MacOS comands.&lt;/p&gt;

&lt;p&gt;Enable this in your profile with the below:&lt;/p&gt;
&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;Set-PSReadLineKeyHandler&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Key&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;UpArrow&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Function&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;HistorySearchBackward&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# Menu Complete for tab completion is really nice and gives you parameter information during selection.&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Set-PSReadLineKeyHandler&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Key&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Tab&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Function&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;MenuComplete&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Set-PSReadLineOption&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-HistorySearchCursorMovesToEnd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;$true&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;After seeing &lt;a href=&quot;https://twitter.com/TylerLeonhardt&quot;&gt;Tyler Leonhardt (@TylerLeonhardt)&lt;/a&gt; example in the twitter thread I decided to give &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Posh-Git&lt;/code&gt; a go with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Oh-My-Posh&lt;/code&gt; and I am very pleased with the result.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Git auto-completion&lt;/li&gt;
  &lt;li&gt;VCS status in my prompt&lt;/li&gt;
  &lt;li&gt;Easy customisation&lt;/li&gt;
  &lt;li&gt;Consistent Powerlevel theme between zsh and PS&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;Import-Module&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;posh-git&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Import-Module&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;oh-my-posh&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$gitpromptsettings&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;DefaultPromptAbbreviateHomeDirectory&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;$true&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$GitPromptSettings&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;DefaultPromptSuffix&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'`n❯❯ '&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$nestedPromptLevel&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# This is to prevent an issue where iterm2 throws an error every time the prompt is run&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;LC_TERMINAL&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-eq&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;iTerm2&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ThemeSettings&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ConsoleTitle&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;$false&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Set-Theme&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Powerlevel10k-Lean&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ThemeSettings&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CurrentUser&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;$null&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ThemeSettings&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PromptSymbols&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'promptindicator'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;`n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;{0} &quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ConvertFromUtf32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x276F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;One other cool thing that I added to my profile recently was enabling the ability to traverse folders without having to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Set-Location&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cd&lt;/code&gt; which is consistent behaviour with zsh.&lt;/p&gt;

&lt;p&gt;I found an old blog post on devblogs where &lt;a href=&quot;https://twitter.com/lzybkr&quot;&gt;Jason Shirk(@lzybkr)&lt;/a&gt; had written how to do this so I modified it slightly for my needs so that any command you type is evaluated and if it’s a path it will traverse into that directory. This is yet more consistency between the two shells and saves on the typing. Coupled with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;..&lt;/code&gt; &amp;amp; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;...&lt;/code&gt; aliases it makes navigation so pleasant.&lt;/p&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Taken from here: https://devblogs.microsoft.com/scripting/whats-in-your-powershell-profile-powershell-team-favorites/&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# Changing directories without having to type cd to replicate zsh&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;$ExecutionContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;InvokeCommand&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CommandNotFoundAction&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$commandName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;System.Management.Automation.CommandLookupEventArgs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$eventArgs&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# Remove the ‘get-‘ prefix that confuses Test-Path after we produce&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# something that is path like after the get-.&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$commandName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;StartsWith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;‘&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;get-&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;‘&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$commandName&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$commandName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Substring&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  

    &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# If the command looks like a location, just switch to that directory&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Test-Path&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Path&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$commandName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$eventArgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CommandScriptBlock&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Set-Location&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-LiteralPath&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$commandName&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetNewClosure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I have updated the gist of my profile &lt;a href=&quot;https://gist.github.com/brettmillerb/467e4ee2d7f8e97897f106a5534f884b&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/24279339/91505604-df41f880-e8c7-11ea-9dcd-cd46e06c4923.png&quot; alt=&quot;Pwsh prompt MacOS&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;remote-development-extension&quot;&gt;Remote Development Extension&lt;/h2&gt;
&lt;p&gt;I wrote about &lt;a href=&quot;https://millerb.co.uk/2019/11/27/Developing-Pwsh-Az-Functions-In-Docker-And-VsCode.html&quot;&gt;Developing Pwsh Azure Functions inside a Container&lt;/a&gt; some time ago and it was really my my first foray into using docker as a daily tool but this is now how I work every day for most of the repositories and code that I write.&lt;/p&gt;

&lt;p&gt;The above post covers pretty much everything you need to get started with that but using docker as a development enviroment has been a game changer.&lt;/p&gt;

&lt;p&gt;I use Azure functions a lot, both PowerShell and C# and being able to develop these in a container without having to have the Az Functions Core tools or npm or any of the extensions installed locally is a dream. You need to check it out if you haven’t already.&lt;/p&gt;

&lt;h2 id=&quot;jq&quot;&gt;JQ&lt;/h2&gt;
&lt;p&gt;So I have written already about &lt;a href=&quot;https://millerb.co.uk/2019/12/07/Az-CLI-vs-Az-PowerShell.html&quot;&gt;how I use AzureCLI &amp;amp; PowerShell together&lt;/a&gt; but I was also made aware of &lt;a href=&quot;https://stedolan.github.io/jq/&quot;&gt;jq&lt;/a&gt; which I suppose is similar to how I would normally use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ConvertFrom-Json&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ConvertFrom-Json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I have been trying to get better with this instead of just defaulting to PowerShell but the data manipulation and objects that Pwsh provides it’s a tough ask.&lt;/p&gt;

&lt;h2 id=&quot;other-things&quot;&gt;Other Things&lt;/h2&gt;
&lt;p&gt;My &lt;a href=&quot;https://millerb.co.uk/2019/02/28/My-Vscode-Setup.html&quot;&gt;original post&lt;/a&gt; is still very much valid and most of the shortcuts I have copied over and work just fine.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://millerb.co.uk/2019/02/28/My-Vscode-Setup.html#git-profiles&quot;&gt;git profiles&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://millerb.co.uk/2019/02/28/My-Vscode-Setup.html#git-aliases&quot;&gt;git aliases&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some of the items are now available by default in VSCode or in the PowerShell Extension but some of them I will never be able to live without.&lt;/p&gt;

&lt;p&gt;I will attempt to add to this post when I make additions or substractions to my setup but this is a good start&lt;/p&gt;</content><author><name>Brett Miller</name></author><category term="PowerShell" /><category term="MacOs" /><category term="VSCode" /><category term="Productivity" /><summary type="html">WARNING! - Long Post Alert…..Again. I previously wrote a post on this which was very popular as I tried to document all of my productivity hacks and shortcuts that I use on a daily basis to assist in writing PowerShell. That post is My VSCode Setup. I have since moved from a Windows laptop to MacOS so I wanted to make a note of customisations and changes so I had a place to track all of them but other people may also find some of them handy. Some stuff won’t have changed too much because, well…..there was no need but my way of working has shifted slightly and I spend more time with a split terminal between bash and PowerShell.</summary></entry><entry><title type="html">Azure CLI vs Azure PowerShell - Why not both?</title><link href="https://millerb.co.uk/2019/12/07/Az-CLI-vs-Az-PowerShell.html" rel="alternate" type="text/html" title="Azure CLI vs Azure PowerShell - Why not both?" /><published>2019-12-07T00:00:00+00:00</published><updated>2019-12-07T00:00:00+00:00</updated><id>https://millerb.co.uk/2019/12/07/Az-CLI-vs-Az-PowerShell</id><content type="html" xml:base="https://millerb.co.uk/2019/12/07/Az-CLI-vs-Az-PowerShell.html">&lt;p&gt;I see quite a bit of conversation about whether people prefer Azure CLI or PowerShell for managing their Azure resources and if like me, you have come from managing on-premises workloads before moving over to managing cloud magic, you will likely want to use the tools that are familiar to you. So naturally I tend to lean towards PowerShell but I have been using the CLI more frequently so I wanted to highlight that it doesn’t have to be one or the other.&lt;/p&gt;

&lt;p&gt;The Azure PowerShell module is now on it’s 3rd iteration. You had the original &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Azure&lt;/code&gt; module followed by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AzureRM&lt;/code&gt; and now you have the cross platform &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Az&lt;/code&gt; module.&lt;/p&gt;

&lt;p&gt;The Azure CLI, if you’re used to powershell, is not very familiar syntax wise, it has very limited tab completion and the more in depth you go you have to start referencing the docs for things like &lt;a href=&quot;http://jmespath.org/&quot;&gt;JMESPath&lt;/a&gt; query language.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;As engineers I think it is natural to look at how we can manage cloud workloads with with the skills and tools that we already have but what if we’re missing out and what if you have no choice but to adopt something else?&lt;/p&gt;

&lt;p&gt;Learning a new CLI can take time and when frustration sets in it’s easy to think about going back to your PowerShell comfort blanket.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if these tools are easier to use?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if they are better?&lt;/strong&gt; 😱&lt;/p&gt;

&lt;p&gt;Personally I find Az CLI really performant and the built-in help is really concise. It shows mandatory parameters as well as examples and it covers a good 98% of what I need when I am working at the command line in the console.&lt;/p&gt;

&lt;h2 id=&quot;azure-cli-vs-powershell--&quot;&gt;Azure CLI ‘vs’ PowerShell  🥊&lt;/h2&gt;

&lt;p&gt;Naturally after working with PowerShell for quite some time you become accustomed to it’s Object output, however when you first start playing with Azure CLI you suddenly start getting raw JSON, which if you’re returning more than one resource is going to fill your screen and be difficult to read.&lt;/p&gt;

&lt;p&gt;Azure CLI does however offer different output formats (&lt;a href=&quot;https://docs.microsoft.com/en-us/cli/azure/format-output-azure-cli?view=azure-cli-latest&quot;&gt;Output Docs&lt;/a&gt;)&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;output&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Description&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;json&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;JSON string. This setting is the default.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;jsonc&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;Colorized JSON.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;yaml&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;YAML, a machine-readable alternative to JSON.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;table&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;ASCII table with keys as column headings.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;tsv&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;Tab-separated values, with no keys&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The downside is when you start looking at wanting anything other than the default properties when using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;table&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tsv&lt;/code&gt; output then you have to starting googling the JMESPath syntax or digging through examples to get what you want. This is where the frustation sets in as you already know how to do this with PowerShell.&lt;/p&gt;

&lt;p&gt;Lets have a look at the different ways to retrieve some results using Azure Cli and PowerShell.&lt;/p&gt;

&lt;h3 id=&quot;az-cli-query&quot;&gt;Az CLI Query&lt;/h3&gt;
&lt;p&gt;Let’s list all of the FunctionApp’s available in the current account. We want to change the resourceGroup property to resource because I needed a contrived example and we also want the name and defaultHostName properties.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;az functionapp list --query &quot;[].{resource:resourceGroup, name:name, defaultHostName:defaultHostName}&quot; -o table

Resource    Name          DefaultHostName
----------  ---------     ---------------------------
poshbotio   poshbotio     poshbotio.azurewebsites.net
Myfunction  MyFunction    myfunction.azurewebsites.net
Functest    HttpFunction  httpfunction.azurewebsites.net
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;✅ Azure CLI is available X-Plat including in Cloud Shell.&lt;/p&gt;

&lt;p&gt;❌ JMESPAth is unfamiliar syntax, all of the braces are not very nice to type.&lt;/p&gt;

&lt;h2 id=&quot;native-powershell&quot;&gt;Native PowerShell&lt;/h2&gt;
&lt;p&gt;Using the PowerShell cmdlets to retrieve exactly the same. We have to use a calculated property to change the resource property. Get all of the results and select the properties you want with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Select-Object&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Get-AzFunctionApp | Select-Object @{n='resource';e={$_.resourceGroup}}, name, defaultHostName

Resource    Name          DefaultHostName
----------  ---------     ---------------------------
poshbotio   poshbotio     poshbotio.azurewebsites.net
Myfunction  MyFunction    myfunction.azurewebsites.net
Functest    HttpFunction  httpfunction.azurewebsites.net
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;✅ Available X-Plat including in Cloud Shell.&lt;/p&gt;

&lt;p&gt;✅ Familiar PowerShell syntax, Calculated Properties are familiar but still a bit meh.&lt;/p&gt;

&lt;p&gt;❌ FunctionApp cmdlets are only available in the preview Az.Functions module to date.&lt;/p&gt;

&lt;h2 id=&quot;hybrid-az-cli--powershell&quot;&gt;Hybrid Az Cli &amp;amp; PowerShell&lt;/h2&gt;
&lt;p&gt;Using a combination of the two. Retreive the results with Azure CLI in raw JSON, then convert it to a powerShell object with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ConvertFrom-Json&lt;/code&gt; and use the familar &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Select-Object&lt;/code&gt; syntax. Performant and familiar.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;az functionapp list | ConvertFrom-Json | select-Object @{n='resource';e={$_.resourceGroup}}, name, defaultHostName

Resource    Name          DefaultHostName
----------  ---------     ---------------------------
poshbotio   poshbotio     poshbotio.azurewebsites.net
Myfunction  MyFunction    myfunction.azurewebsites.net
Functest    HttpFunction  httpfunction.azurewebsites.net
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;✅ Available Cross Platform including in Cloud Shell.&lt;/p&gt;

&lt;p&gt;✅ No need to install extra PowerShell modules.&lt;/p&gt;

&lt;p&gt;✅ Basic Az CLI knowledge required so good discoverability.&lt;/p&gt;

&lt;p&gt;✅ Familiar syntax for consuming and manipulating the output with PowerShell.&lt;/p&gt;

&lt;h2 id=&quot;deciding-which-to-use&quot;&gt;Deciding which to use&lt;/h2&gt;
&lt;p&gt;I don’t really have a preference between Azure CLI and PowerShell but if you look at the output above you get exactly the same result using all three methods.&lt;/p&gt;

&lt;p&gt;I do tend to lean towards the hybrid of the two as it is familiar to me without having to learn the nuances of JMESPath query filters but also gives me the flexibility of being able to pipeline that object into other PowerShell command or a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Export-*&lt;/code&gt; cmdlet.&lt;/p&gt;

&lt;h3 id=&quot;azure-cli-built-in-help&quot;&gt;Azure CLI Built-In Help&lt;/h3&gt;
&lt;p&gt;I always brag about how amazing the PowerShell help system is for people learning PowerShell but I also think that the team who built the Azure CLI have done an amazing job on the builtin help.&lt;/p&gt;

&lt;p&gt;Typing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;az -h&lt;/code&gt; will show you the extensions available to be used.&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;❯❯ az -h

Group
    az

Subgroups:
    account               : Manage Azure subscription information.
    acr                   : Manage private registries with Azure Container Registries.
    ad                    : Manage Azure Active Directory Graph entities needed for Role Based
                            Access Control.
    advisor               : Manage Azure Advisor.
    aks                   : Manage Azure Kubernetes Services.
    ams         [Preview] : Manage Azure Media Services resources.
    apim        [Preview] : Manage Azure API Management services.
    appconfig   [Preview] : Manage App Configurations.
    appservice            : Manage App Service plans.
    backup      [Preview] : Manage Azure Backups.
:
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To find out more about the usage of these extensions you can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;az {subGroup} -h&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;az functionapp -h
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Drilling down further&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;az functionpp list -h
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It lists examples with each use of the help switch and lists the available sub-groups, commands and examples&lt;/p&gt;

&lt;h2 id=&quot;az-find-for-examples-and-discoverability&quot;&gt;Az Find for Examples and Discoverability&lt;/h2&gt;

&lt;p&gt;I didn’t know this existed until recently but it’s an awesome tool for discoverability at the command line when using Az CLI.&lt;/p&gt;

&lt;p&gt;Here is what the help says about the command&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Command
    az find : I'm an AI robot, my advice is based on our Azure documentation as well as the usage patterns of Azure CLI and Azure ARM users. Using me improves Azure products and documentation.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And here is what it says about the examples we have been using. This can be really helpful when you’re getting used to the Azure CLI but also if you’re just unsure about how a specific command should work&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;❯❯ az find &quot;az functionapp list&quot;
Finding examples...

Here are the most common ways to use [az functionapp list]:

List default host name and state for all function apps.
az functionapp list --query &quot;.{hostName: defaultHostName, state: state}&quot;

List all running function apps.
az functionapp list --query &quot;&quot;

List available locations for running function apps.
az functionapp list-consumption-locations
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;/h3&gt;
&lt;p&gt;Find what works for you. The cloud is a big magical place where people are doing amazing things, with this comes a variety of new tools for managing all aspects of the cloud.&lt;/p&gt;

&lt;p&gt;I’ve found a hybrid pattern that works for me when I am using the console for discoverability or information gathering. It gives me the speed of the Azure CLI with the familiar syntax of PowerShell so I can be productive without having to learn an entire new command line tool.&lt;/p&gt;

&lt;p&gt;Try not to build something just for the sake of building something. The PowerShell community is definitely guilty of building a tool just because it suits our needs. Take a look at what is already out there and maybe think about contributing to that instead, that way an entire ecosystem benefits from your take on it.&lt;/p&gt;

&lt;p&gt;The more that I use the Azure CLI, the more I am inclined to just dive in and use it, it is available in both bash and PowerShell on my Mac &amp;amp; in cloud shell in browser so I can just fire it up without having to think about it.&lt;/p&gt;</content><author><name>Brett Miller</name></author><category term="Azure" /><category term="PowerShell" /><category term="Azure CLI" /><summary type="html">I see quite a bit of conversation about whether people prefer Azure CLI or PowerShell for managing their Azure resources and if like me, you have come from managing on-premises workloads before moving over to managing cloud magic, you will likely want to use the tools that are familiar to you. So naturally I tend to lean towards PowerShell but I have been using the CLI more frequently so I wanted to highlight that it doesn’t have to be one or the other. The Azure PowerShell module is now on it’s 3rd iteration. You had the original Azure module followed by AzureRM and now you have the cross platform Az module. The Azure CLI, if you’re used to powershell, is not very familiar syntax wise, it has very limited tab completion and the more in depth you go you have to start referencing the docs for things like JMESPath query language.</summary></entry><entry><title type="html">Developing PowerShell Azure Functions Locally in a Container</title><link href="https://millerb.co.uk/2019/11/27/Developing-Pwsh-Az-Functions-In-Docker-And-VsCode.html" rel="alternate" type="text/html" title="Developing PowerShell Azure Functions Locally in a Container" /><published>2019-11-27T00:00:00+00:00</published><updated>2019-11-27T00:00:00+00:00</updated><id>https://millerb.co.uk/2019/11/27/Developing-Pwsh-Az-Functions-In-Docker-And-VsCode</id><content type="html" xml:base="https://millerb.co.uk/2019/11/27/Developing-Pwsh-Az-Functions-In-Docker-And-VsCode.html">&lt;p&gt;I have recently just switched work machines from a Windows laptop to a Macbook. I’ve not had much exposure to anything other than Windows but I live on the command line most of the time and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;'mac' -eq 'linux'&lt;/code&gt; anyway right?&lt;/p&gt;

&lt;h2 id=&quot;keeping-my-machine-tidy&quot;&gt;Keeping My Machine Tidy&lt;/h2&gt;

&lt;p&gt;Part of this switch I made it my mission to try and keep my machine as tidy as possible and with that I didn’t want to immediately go and install a load of stuff that I was then going to have to manage and update…..especially when i only needed some of it for specific projects.&lt;/p&gt;

&lt;p&gt;I have been spending a considerable amount of my down time watching people do live coding on twitch and in particular &lt;a href=&quot;https://twitter.com/michaeljolley&quot;&gt;Michael Jolley (Twitter)&lt;/a&gt; and I was particularly intrigued by him showing how he develops inside of docker containers so I decided to give it a try.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h2 id=&quot;pre-requisites&quot;&gt;Pre-Requisites&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Visual Studio Code&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.docker.com/products/docker-desktop&quot;&gt;Docker Desktop&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack&quot;&gt;Remote Development Extension&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The installation requirements for Azure Functions are on &lt;a href=&quot;https://docs.microsoft.com/en-gb/azure/azure-functions/functions-run-local#install-the-azure-functions-core-tools&quot;&gt;docs.microsoft.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;On both Mac and Windows this requires the Azure Functions Extension Bundle or the .NET SDK and on Windows you’ll have to install npm and node.js so not having to install anything locally is good.&lt;/p&gt;

&lt;h2 id=&quot;setting-up-your-workspace&quot;&gt;Setting up your Workspace&lt;/h2&gt;

&lt;p&gt;Create a folder on your machine that you want to contain your project.&lt;/p&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;PS&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;New-Item&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-ItemType&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Name&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;MyFirstFunction&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Directory:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;/Users/brett.miller/git/gitpersonal&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UnixMode&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;   &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;           &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Group&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;       &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;LastWriteTime&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;   &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Size&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;--------&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;   &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;----&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;           &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-----&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;       &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-------------&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;   &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;----&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;----&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;drwxr-xr-x&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;brett.miller&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;27/11/2019&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;16:03&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;     &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;MyFirstFunction&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Open that folder in VSCode&lt;/p&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;PS&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;MyFirstFunction&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PS&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;code&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Once you’re inside Visual Studio Code you can open your folder in a container by using the command pallette.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;F1&lt;/code&gt; &amp;gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Remote-Containers: Open Folder In Container&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/24279339/69739952-74914000-1130-11ea-87d0-7078eea0d46c.png&quot; alt=&quot;Remote Container - Open In Folder&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Select the folder you want to open. You will then be presented with the list of available containers from within the extension.&lt;/p&gt;

&lt;p&gt;What you will notice however is that there are options for Azure Functions with C#, Java, Node &amp;amp; Python but there is no container for PowerShell Azure Functions. WTF?!&lt;/p&gt;

&lt;p&gt;Well I have fixed that by opening a &lt;a href=&quot;https://github.com/microsoft/vscode-dev-containers/pull/153&quot;&gt;Pull Request&lt;/a&gt; and adding a container definition which has all of the dependencies required. This is pending release at the time of writing.&lt;/p&gt;

&lt;p&gt;To get access to these prior to release you can grab what you need directly from the &lt;a href=&quot;https://github.com/microsoft/vscode-dev-containers/tree/master/containers/azure-functions-pwsh-6/.devcontainer&quot;&gt;Github Repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Open your folder in VSCode and create another folder called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.devcontainer&lt;/code&gt; then create two files, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;devcontainer.json&lt;/code&gt; &amp;amp; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dockerfile&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Copy the contents of the two files from github to their corresponding files on your machine.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/24279339/69741312-c044e900-1132-11ea-8aaf-4d1dfd91fc88.png&quot; alt=&quot;Local Folder with devcontainer setup&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now you can reopen the folder in your container with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Remote-Containers: Reopen in Container&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This may take a while as docker now needs to download the necessary image and work through the docker file installing dependencies so that all tools are available. Subsequent runs should not take as long as it will reuse the image it creates.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/24279339/69741529-1e71cc00-1133-11ea-836f-7d2660e88654.png&quot; alt=&quot;Reopen in Container&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Once it has finished building the docker file it will open a terminal defaulting to PowerShell.&lt;/p&gt;

&lt;p&gt;You can confirm this with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$PSVersionTable&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;PS&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;$PSVersionTable&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                           &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;----&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                           &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-----&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PSVersion&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                      &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;6.2.3&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PSEdition&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                      &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Core&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GitCommitId&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;6.2.3&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;OS&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                             &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Linux&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;4.9.184-linuxkit&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;#1 SMP Tue Jul 2 22:58:16 UTC 2019&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Platform&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                       &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Unix&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PSCompatibleVersions&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;           &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;2.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;3.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;4.0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;…&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PSRemotingProtocolVersion&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;2.3&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SerializationVersion&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;           &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;1.1.0.1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;WSManStackVersion&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;              &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;3.0&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now that you have your folder opened in a container with all of the necessary tools you can start initialising your Function Project.&lt;/p&gt;

&lt;p&gt;To see how to do that you can follow this post I created to get you started:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://millerb.co.uk/2019/11/27/Getting-Started-Pwsh-Az-Functions-Part-1.html&quot;&gt;PowerShell &amp;amp; Azure Functions - Part 1&lt;/a&gt;&lt;/p&gt;</content><author><name>Brett Miller</name></author><category term="Azure Functions" /><category term="PowerShell" /><category term="Docker" /><category term="Remote Development Extension" /><category term="Serverless" /><summary type="html">I have recently just switched work machines from a Windows laptop to a Macbook. I’ve not had much exposure to anything other than Windows but I live on the command line most of the time and 'mac' -eq 'linux' anyway right? Keeping My Machine Tidy Part of this switch I made it my mission to try and keep my machine as tidy as possible and with that I didn’t want to immediately go and install a load of stuff that I was then going to have to manage and update…..especially when i only needed some of it for specific projects. I have been spending a considerable amount of my down time watching people do live coding on twitch and in particular Michael Jolley (Twitter) and I was particularly intrigued by him showing how he develops inside of docker containers so I decided to give it a try.</summary></entry><entry><title type="html">PowerShell &amp;amp; Azure Functions - Part 1</title><link href="https://millerb.co.uk/2019/11/27/Getting-Started-Pwsh-Az-Functions-Part-1.html" rel="alternate" type="text/html" title="PowerShell &amp;amp; Azure Functions - Part 1" /><published>2019-11-27T00:00:00+00:00</published><updated>2019-11-27T00:00:00+00:00</updated><id>https://millerb.co.uk/2019/11/27/Getting-Started-Pwsh-Az-Functions-Part-1</id><content type="html" xml:base="https://millerb.co.uk/2019/11/27/Getting-Started-Pwsh-Az-Functions-Part-1.html">&lt;p&gt;I have been using Azure Functions for a little while and I published my initial thoughts on &lt;a href=&quot;https://millerb.co.uk/2019/11/26/Azure-Functions-and-PowerShell.html&quot;&gt;Azure Functions and their use cases here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this post I want to cover how to get started with Functions and a few lessons learned and I wanted to collect together the documentation I used to get up and running which at present lives in various places on the Microsoft Docs site.&lt;/p&gt;

&lt;h2 class=&quot;no_toc&quot; id=&quot;what-are-azure-functions&quot;&gt;What are Azure Functions&lt;/h2&gt;

&lt;p&gt;Simply put they are a serverless solution in Azure which allow you to run code without having to worry about where it is running or maintaining the underlying infrastructure.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;You can read a whole lot more about Azure Functions in the &lt;a href=&quot;https://docs.microsoft.com/en-gb/azure/azure-functions/functions-overview&quot;&gt;documentation&lt;/a&gt; and it can explain a lot better than I can.&lt;/p&gt;

&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#writing-your-first-function&quot; id=&quot;markdown-toc-writing-your-first-function&quot;&gt;Writing Your First Function&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#pre-requisites&quot; id=&quot;markdown-toc-pre-requisites&quot;&gt;Pre-Requisites&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#create-a-local-function-project&quot; id=&quot;markdown-toc-create-a-local-function-project&quot;&gt;Create A Local Function Project&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#function-layout-overview&quot; id=&quot;markdown-toc-function-layout-overview&quot;&gt;Function Layout Overview&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#scaffolding&quot; id=&quot;markdown-toc-scaffolding&quot;&gt;Scaffolding&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#your-function---the-fun-stuff&quot; id=&quot;markdown-toc-your-function---the-fun-stuff&quot;&gt;Your Function - The Fun Stuff&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#running--debugging-your-function&quot; id=&quot;markdown-toc-running--debugging-your-function&quot;&gt;Running &amp;amp; Debugging Your Function&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#running-your-function-locally&quot; id=&quot;markdown-toc-running-your-function-locally&quot;&gt;Running Your Function Locally&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#triggering-your-function&quot; id=&quot;markdown-toc-triggering-your-function&quot;&gt;Triggering your Function&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#azure-functions-methods&quot; id=&quot;markdown-toc-azure-functions-methods&quot;&gt;Azure Functions Methods&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#summary&quot; id=&quot;markdown-toc-summary&quot;&gt;Summary&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#whats-next&quot; id=&quot;markdown-toc-whats-next&quot;&gt;What’s Next?&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#references--links&quot; id=&quot;markdown-toc-references--links&quot;&gt;References &amp;amp; Links&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;writing-your-first-function&quot;&gt;Writing Your First Function&lt;/h2&gt;
&lt;p&gt;I will go over how to write an Azure Function using Visual Studio Code as that is by the best development experience&lt;/p&gt;

&lt;h3 id=&quot;pre-requisites&quot;&gt;Pre-Requisites&lt;/h3&gt;
&lt;p&gt;You can find the pre-requisites and installation instructions in the &lt;a href=&quot;https://docs.microsoft.com/en-gb/azure/azure-functions/functions-run-local#install-the-azure-functions-core-tools&quot;&gt;Microsoft Docs&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;PowerShell 6+&lt;/li&gt;
  &lt;li&gt;Visual Studio Code (obviously)&lt;/li&gt;
  &lt;li&gt;Node.js which includes npm&lt;/li&gt;
  &lt;li&gt;Azure Functions Core Tools&lt;/li&gt;
  &lt;li&gt;.NET Core SDK - &lt;em&gt;I have this installed but you can avoid that with the extension bundles&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also use the Remote Development Extension and containers to run and debug your functions but there is no official docker image for PowerShell available. I have however created a post to show you how to build your own.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://millerb.co.uk/2019/11/27/Developing-Pwsh-Az-Functions-In-Docker-And-VsCode.html&quot;&gt;Developing PowerShell Azure Functions In Docker And VsCode&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;create-a-local-function-project&quot;&gt;Create A Local Function Project&lt;/h3&gt;
&lt;p&gt;Create a folder where your Function will be contained&lt;/p&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;New-Item&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-ItemType&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Name&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;MyFirstFunction&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;MyFirstFunction&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now that you’re in your project folder initialise your function. Select PowerShell from the list and it will&lt;/p&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;PS&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;/root/MyFirstFunction&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Select&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;worker&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;runtime:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dotnet&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;python&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; 
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;powershell&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Choose&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;option:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;powershell&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Writing&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;profile.ps1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Writing&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;requirements.psd1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Writing&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;gitignore&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Writing&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;host.json&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Writing&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;local.settings.json&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Writing&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;/root/MyFirstFunction/.vscode/extensions.json&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You then need to create your first PowerShell function within your initialised folder and select the trigger type.&lt;/p&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;PS&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;/root/MyFirstFunction&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Select&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;template:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Azure&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Blob&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Storage&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Azure&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Cosmos&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Azure&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Event&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Grid&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Azure&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Event&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Hub&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HTTP&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IoT&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Hub&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Event&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Hub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Azure&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Queue&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Storage&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SendGrid&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;9.&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Azure&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Service&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Bus&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Queue&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Azure&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Service&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Bus&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Topic&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Timer&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Choose&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;option:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HTTP&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;Function&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HttpTrigger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HttpTriggerFunction&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Writing&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;/root/MyFirstFunction/MyFirstFunction/run.ps1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Writing&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;/root/MyFirstFunction/MyFirstFunction/function.json&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;The&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;MyFirstFunction&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;was&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;created&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;successfully&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;the&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;HTTP trigger&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;template.&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Your folder structure will now have a sub-folder with the name you gave to your function.&lt;/p&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;Directory:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;/root/MyFirstFunction&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Mode&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;LastWriteTime&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;         &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;----&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-------------&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;         &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;------&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;----&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d-----&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;          &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;11/26/19&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;4:26&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;PM&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;HttpTriggerFunction&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;------&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;          &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;/26/19&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;4:26&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;PM&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;             &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;72&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;host.json&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;------&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;          &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;/26/19&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;4:26&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;PM&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;142&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;local.settings.json&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;------&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;          &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;/26/19&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;4:26&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;PM&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;882&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;profile.ps1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;------&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;          &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;/26/19&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;4:26&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;PM&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;273&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;requirements.psd1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Your first PowerShell Azure Function is ready to play with 😁&lt;/p&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Open the current folder in VSCode&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;code&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;function-layout-overview&quot;&gt;Function Layout Overview&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/24279339/69654070-1b5fd880-106c-11ea-98d8-e027a51df4e4.png&quot; alt=&quot;Folder Screenshot in VSCode&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;scaffolding&quot;&gt;Scaffolding&lt;/h3&gt;

&lt;p&gt;The majority of the contents of the folder are used to assist with deploying and configuring of your Function.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;.gitignore
    &lt;ul&gt;
      &lt;li&gt;This is a templated gitignore file which contains the common files which you don’t want to commit to git. Things like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;local.settings.json&lt;/code&gt; which is used for storing secrets for local debugging.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;host.json
    &lt;ul&gt;
      &lt;li&gt;This is for setting global configuration settings for your functions. There are lots of options to configure there but not much you have to worry about at first. &lt;a href=&quot;https://docs.microsoft.com/en-us/azure/azure-functions/functions-host-json&quot;&gt;Host.json reference documentation&lt;/a&gt; is here and covers all of the possible options.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;local.settings.json
    &lt;ul&gt;
      &lt;li&gt;When running and debugging your function locally, app settings are read from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;local.settings.json&lt;/code&gt; file. The possible settings for local development are covered in &lt;a href=&quot;https://docs.microsoft.com/en-us/azure/azure-functions/functions-run-local#local-settings-file&quot;&gt;this article&lt;/a&gt;.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;profile.ps1
    &lt;ul&gt;
      &lt;li&gt;this is only required if your function is going to require authentication for interaction with other Azure resources within your tenant. The comments in the file are self-explanatory.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;requirements.psd1
    &lt;ul&gt;
      &lt;li&gt;This is specified to manage your dependencies and the host will automatically download dependencies from the PowerShell Gallery for you so you don’t have to ship modules with your code. It is recommended to pin to a specific major version of a module to prevent breaking changes. &lt;a href=&quot;https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference-powershell#dependency-management&quot;&gt;Dependency Management Docs&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;your-function---the-fun-stuff&quot;&gt;Your Function - The Fun Stuff&lt;/h3&gt;

&lt;p&gt;Within your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HttpTriggerFunction&lt;/code&gt; folder you have your actual code file and information about bindings for this particular function.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;function.json
    &lt;ul&gt;
      &lt;li&gt;This is where your binding information and parameters are defined. You may need to modify these if you’re using something like Azure Service Bus Queue trigger. &lt;a href=&quot;https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-expressions-patterns&quot;&gt;Triggers &amp;amp; Bindings Docs&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;run.ps1
    &lt;ul&gt;
      &lt;li&gt;This is the powershell code that makes up your function and where you will spend most of your time.&lt;/li&gt;
      &lt;li&gt;It consists of a param block where content is passed into your function, the main body which interacts with the content, and an output which utilises an Azure Functions specific cmdlet called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Push-OutputBinding&lt;/code&gt; for passing content back out of your function. &lt;a href=&quot;https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference-powershell#writing-output-data&quot;&gt;Push-Outputbinding Docs&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/24279339/69727203-f164ef80-1119-11ea-81a4-656ff32a604a.png&quot; alt=&quot;Sample Function Image&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;running--debugging-your-function&quot;&gt;Running &amp;amp; Debugging Your Function&lt;/h2&gt;

&lt;p&gt;One of the best things about developing Azure Functions in Visual Studio Code is the fact that all of the tools that you need to write, test, debug and deploy your Azure Function is available to you out of the box.&lt;/p&gt;

&lt;h3 id=&quot;running-your-function-locally&quot;&gt;Running Your Function Locally&lt;/h3&gt;

&lt;p&gt;You can check that your function works as intended locally with the Function Core Tools. The local runtime is the same runtime that hosts your function app in Azure so it saves a tonne of time having to redeploy to test minor changes.&lt;/p&gt;

&lt;p&gt;To run your function locally navigate to your function project folder and start the runtime.&lt;/p&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;PS&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;/root/MyFirstFunction&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

                  &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%%%%%%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                 &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%%%%%%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;   &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%%%%%%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;@@&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;   &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%%%%%%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;@@&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
       &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;@@@&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%%%%%%%%%%%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;@@@&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
     &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;@@&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%%%%%%%%%%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;@@&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
       &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;@@&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;         &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%%%%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;       &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;@@&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
         &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;@@&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%%%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;       &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;@@&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
           &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;@@&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;@@&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Azure&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Functions&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Core&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Tools&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;2.7&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;1846&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Commit&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;hash:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;458c671341fda1c52bd46e1aa8943cb26e467830&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;Function&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Runtime&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Version:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;2.0.12858.0&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Skipping&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'FUNCTIONS_WORKER_RUNTIME'&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;settings&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;as&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'s already defined in current environment variables.

Hosting environment: Production
Content root path: /root/MyFirstFunction
Now listening on: http://0.0.0.0:7071
Application started. Press Ctrl+C to shut down.

Http Functions:

        HttpTriggerFunction: [GET,POST] http://localhost:7071/api/HttpTriggerFunction
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Alongside from pretty trick ASCII art you get some information about your Function Runtime, the address and port the host is listening on, the methods your function supports and the URI that you can use to trigger the function.&lt;/p&gt;

&lt;p&gt;Any logs from the function are then output to the console so if you need to see what is happening within your code you can use the age old tactic of littering it with output.&lt;/p&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;/27/19&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;2:24:11&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;PM&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;INFORMATION&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PowerShell&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HTTP&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;processed&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;request.&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;triggering-your-function&quot;&gt;Triggering your Function&lt;/h3&gt;

&lt;p&gt;You can open the URI in your browser which will trigger the function and you should see the output below.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/24279339/69731038-0ee98780-1121-11ea-81a4-93698abc9fe9.png&quot; alt=&quot;Localhost Functions Browser&quot; /&gt;&lt;/p&gt;

&lt;p&gt;You can see from the output that this is the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;else&lt;/code&gt; block of the code telling you to provide a query parameter to your function.&lt;/p&gt;

&lt;p&gt;If you change the URI to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http://127.0.0.1:7071/api/HttpTriggerFunction?name=brett&lt;/code&gt; you will get the following output.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/24279339/69731399-c088b880-1121-11ea-8144-c583b8665956.png&quot; alt=&quot;Localhost Functions Query Output&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Testing this in the browser is fine when your Azure Function supports GET method but in order to test a POST method then you will need to use PowerShell or Postman so you can pass a JSON payload.&lt;/p&gt;

&lt;h3 id=&quot;azure-functions-methods&quot;&gt;Azure Functions Methods&lt;/h3&gt;

&lt;p&gt;So if you’ve used PowerShell to interact with API’s then you’ll likely be aware of the HTTP Methods that are used for RESTful services. It’s the same principle for Azure Functions and you should take this into account when designing your Functions as the way you handle your input parameters will differ.&lt;/p&gt;

&lt;p&gt;When your function is triggered with the GET method then the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Query&lt;/code&gt; property of your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$Request&lt;/code&gt; payload will be populated but if the POST method is used then the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Body&lt;/code&gt; property will be used.&lt;/p&gt;

&lt;p&gt;The methods are defined in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;function.json&lt;/code&gt; and because the example project has both GET and POST then it checks for each of the properties accordingly&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;bindings&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;authLevel&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;function&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;httpTrigger&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;direction&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;in&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Request&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;methods&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;get&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;post&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Check to see if the payload has a query value - GET method&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$name&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Query&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# If query is not populated then check the Body value - POST method&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-not&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$name&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Body&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;Working with PowerShell in Azure Functions has been an awesome experience. Being able to develop and run them locally without having to constantly push my changes to Azure made the learning process so easy.&lt;/p&gt;

&lt;p&gt;The way you work with Functions is very familiar so you can bring what you already know about writing a PowerShell Function and with very little modification, start working with your cloud workloads in a much leaner way. Something that would previously have been a scheduled script in Azure Automation can now be reactive and if you’re on a consumption plan then it will cost nothing at all.&lt;/p&gt;

&lt;p&gt;One of the most difficult parts of getting to grips with Azure Functions in general is the sheer amount of documentation that resides on slightly different pages dependent on what information you’re looking for. It was very easy to overlook parts of the documentation or quite frequently had to piece together parts from the examples in other programming languages as PowerShell documentation within Azure Functions is lacking a little.&lt;/p&gt;

&lt;h2 id=&quot;whats-next&quot;&gt;What’s Next?&lt;/h2&gt;

&lt;p&gt;I have another follow up post in the making which will cover local debugging, deploying your function and some more in depth parts of PowerShell in Azure Functions as well as some of the edge cases I encountered.&lt;/p&gt;

&lt;h2 id=&quot;references--links&quot;&gt;References &amp;amp; Links&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-gb/azure/azure-functions/functions-overview&quot;&gt;An introduction to Azure Functions&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-gb/azure/azure-functions/functions-run-local&quot;&gt;Work with Azure Functions Core Tools&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/azure/azure-functions/functions-host-json&quot;&gt;Host.json reference documentation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/azure/azure-functions/functions-run-local#local-settings-file&quot;&gt;Local settings file&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference-powershell#dependency-management&quot;&gt;Dependency Management&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-expressions-patterns&quot;&gt;Azure Functions Bindings&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference-powershell#writing-output-data&quot;&gt;Writing Output Data&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><author><name>Brett Miller</name></author><category term="PowerShell" /><category term="Azure Functions" /><category term="Serverless" /><summary type="html">I have been using Azure Functions for a little while and I published my initial thoughts on Azure Functions and their use cases here. In this post I want to cover how to get started with Functions and a few lessons learned and I wanted to collect together the documentation I used to get up and running which at present lives in various places on the Microsoft Docs site. What are Azure Functions Simply put they are a serverless solution in Azure which allow you to run code without having to worry about where it is running or maintaining the underlying infrastructure.</summary></entry><entry><title type="html">Azure Functions - Event Driven, Serverless Functions</title><link href="https://millerb.co.uk/2019/11/26/Azure-Functions-and-PowerShell.html" rel="alternate" type="text/html" title="Azure Functions - Event Driven, Serverless Functions" /><published>2019-11-26T00:00:00+00:00</published><updated>2019-11-26T00:00:00+00:00</updated><id>https://millerb.co.uk/2019/11/26/Azure-Functions-and-PowerShell</id><content type="html" xml:base="https://millerb.co.uk/2019/11/26/Azure-Functions-and-PowerShell.html">&lt;p&gt;I’ve been spending a signficant amount of time developing and playing with PowerShell for Azure Functions since they were V1 and they were not as good as they could have been.&lt;/p&gt;

&lt;p&gt;Fortunately they have been in V2 for quite some time and went to General Availability as of Ignite in November ‘19. This means that they can “officially” be used for production workloads with official support.&lt;/p&gt;

&lt;h3 id=&quot;drawing-a-distinction-between-other-azure-offerings&quot;&gt;Drawing a distinction between other Azure Offerings&lt;/h3&gt;

&lt;p&gt;So my initial reaction when I started playing with PowerShell in Azure Functions was that they were so much nicer to work with than Azure Automation but the more I played with them, the more I realisd that they were &lt;strong&gt;NOT&lt;/strong&gt; a direct replacement but an accompaniment.&lt;/p&gt;

&lt;p&gt;Azure Automation is still very useful for automation and long running tasks such as reports and Azure Functions really shine when you want event driven actions.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h3 id=&quot;event-driven---say-what&quot;&gt;Event Driven - Say What?!&lt;/h3&gt;

&lt;p&gt;Events in Azure can mean a number of things and 9 times out of 10 the first Azure Function you will create is an HTTP trigger which is a manual interaction. As you delve deeper you start seeing situations where event driven is at the forefront of what you want to react to.&lt;/p&gt;

&lt;h3 id=&quot;example-scenario&quot;&gt;Example Scenario&lt;/h3&gt;

&lt;p&gt;Azure Key Vault Secret monitoring. This has been in private preview for a while and is still in public preview (&lt;a href=&quot;https://docs.microsoft.com/en-us/azure/key-vault/event-grid-overview&quot;&gt;Read the docs here&lt;/a&gt;).&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Key Vault integration with Event Grid is currently in preview. It allows users to be notified when the status of a secret stored in key vault has changed. A status change is defined as a secret that is about to expire (within 30 days of expiration), a secret that has expired, or a secret that has a new version available. Notifications for all three secret types (key, certificate, and secret) are supported.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With access to the private preview I setup a test Key Vault with some secrets that had various expiry dates. When the secrets approached expiry there was an event posted to Event Grid. I created an Azure Function which subscribed to this event and sent a notification to Slack to notify that there was a secret about to expire.&lt;/p&gt;

&lt;p&gt;The initial evolution of this was to trigger an Azure DevOps pipeline and renew a Let’s Encrypt certificate then release a product in a staging environment with an automatically updated certificate.&lt;/p&gt;

&lt;h3 id=&quot;integration-with-other-azure-services&quot;&gt;Integration With Other Azure Services&lt;/h3&gt;

&lt;p&gt;Azure Functions has first class support for integration with other services and at time of writing this there are numerous triggers and bindings that can be utilised as part of an Azure Functions. &lt;a href=&quot;https://docs.microsoft.com/en-us/azure/azure-functions/functions-triggers-bindings#supported-bindings&quot;&gt;List can be found here&lt;/a&gt; and the number of services are growing.&lt;/p&gt;

&lt;p&gt;This means that you can be reactive to any events that are raisd from your infrastructure in Azure.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;An Azure IaaS VM is created Event can trigger a Function to automatically tag that VM&lt;/li&gt;
  &lt;li&gt;Someone adds an image to blob storage. Azure Function is triggered and uploads that image to congnitive services API and reports back on sentiment analysis for a face in the image.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The options are astounding.&lt;/p&gt;

&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;/h3&gt;

&lt;p&gt;In my humble, and often incorrect, opinion I think that Azure Functions with PowerShell is a match made in heaven for Ops people. Being able to setup automation that automatically reacts to events raised in such a seameless way opens up a new world of managing infrastructure at scale and the cost is pennies.&lt;/p&gt;

&lt;p&gt;I will follow this post up with some additional content around lessons learned and developing Az Functions that hopefully you will get some use out of.&lt;/p&gt;

&lt;h3 id=&quot;additional-reading-material&quot;&gt;Additional Reading Material&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/azure/azure-functions/functions-create-first-function-powershell&quot;&gt;Create your first PowerShell function in Azure&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/azure/azure-functions/functions-triggers-bindings&quot;&gt;Triggers &amp;amp; Bindings&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference-powershell&quot;&gt;Azure Functions PowerShell developer guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><author><name>Brett Miller</name></author><category term="Powershell" /><category term="Azure Functions" /><category term="Serverless" /><summary type="html">I’ve been spending a signficant amount of time developing and playing with PowerShell for Azure Functions since they were V1 and they were not as good as they could have been. Fortunately they have been in V2 for quite some time and went to General Availability as of Ignite in November ‘19. This means that they can “officially” be used for production workloads with official support. Drawing a distinction between other Azure Offerings So my initial reaction when I started playing with PowerShell in Azure Functions was that they were so much nicer to work with than Azure Automation but the more I played with them, the more I realisd that they were NOT a direct replacement but an accompaniment. Azure Automation is still very useful for automation and long running tasks such as reports and Azure Functions really shine when you want event driven actions.</summary></entry></feed>