<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sheldon</title>
    <description>The latest articles on DEV Community by Sheldon (@sheldonhull).</description>
    <link>https://dev.to/sheldonhull</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F99196%2Ff10a99a8-cf88-490e-969b-c2cd7fbaca13.jpg</url>
      <title>DEV Community: Sheldon</title>
      <link>https://dev.to/sheldonhull</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sheldonhull"/>
    <language>en</language>
    <item>
      <title>RSS Feed from Hugo Site With Broken Shortcodes</title>
      <dc:creator>Sheldon</dc:creator>
      <pubDate>Mon, 12 Jul 2021 18:09:06 +0000</pubDate>
      <link>https://dev.to/sheldonhull/rss-feed-from-hugo-site-with-broken-shortcodes-38b2</link>
      <guid>https://dev.to/sheldonhull/rss-feed-from-hugo-site-with-broken-shortcodes-38b2</guid>
      <description>&lt;p&gt;I don't keep up with dev.to for publishing as almost every single post has broken imports from my hugo blog.&lt;br&gt;
For example, gists never work, and require me to convert to the jekyll syntax.&lt;br&gt;
Images often have issues as well. &lt;/p&gt;

&lt;p&gt;Is there some way I can control my dev.to posting, and even better automatically publish from my hugo blog so I don't have to manually do this each time?&lt;br&gt;
(I'm guessing perhaps I'd have to build out a custom api call with github actions or something)&lt;/p&gt;

</description>
      <category>devto</category>
      <category>blog</category>
      <category>rss</category>
      <category>jekyll</category>
    </item>
    <item>
      <title>Cool Way to Compare Features in Note Apps</title>
      <dc:creator>Sheldon</dc:creator>
      <pubDate>Tue, 18 May 2021 18:28:03 +0000</pubDate>
      <link>https://dev.to/sheldonhull/cool-way-to-compare-features-in-note-apps-d0</link>
      <guid>https://dev.to/sheldonhull/cool-way-to-compare-features-in-note-apps-d0</guid>
      <description>&lt;p&gt;Nice little site I came across for comparing various popular knowledge &amp;amp; note taking tools with ability to select features most important to you.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.noteapps.info/apps/compare?note_app=bear%2Bnotion%2Bobsidian&amp;amp;selected_group=appearance#compare-preface"&gt;NoteApps&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note typically a fan of compare based tools, as they often feel like marketing junk, but this was a a pretty cool little implementation.&lt;/p&gt;

</description>
      <category>tech</category>
    </item>
    <item>
      <title>Git Workflow With Git Town</title>
      <dc:creator>Sheldon</dc:creator>
      <pubDate>Tue, 23 Feb 2021 22:23:00 +0000</pubDate>
      <link>https://dev.to/sheldonhull/git-workflow-with-git-town-3h8n</link>
      <guid>https://dev.to/sheldonhull/git-workflow-with-git-town-3h8n</guid>
      <description>&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://bit.ly/2OR6zIf"&gt;Git-Town&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Painful But Powerful
&lt;/h2&gt;

&lt;p&gt;Let’s get this out of the way.&lt;/p&gt;

&lt;p&gt;Git isn’t intuitive.&lt;/p&gt;

&lt;p&gt;It has quite a bit of a learning curve.&lt;/p&gt;

&lt;p&gt;However, with this flexibility comes great flexibility. This tool has powered so much of modern open-source development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimize for the Pain
&lt;/h2&gt;

&lt;p&gt;To improve the development experience some tools can help provide structure.&lt;/p&gt;

&lt;p&gt;This won’t be an attempt to compare every git GUI, or push any specific tooling. It’s more sharing my experience and what I’ve found helps accelerate my usage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tools I’ve Relied On
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://bit.ly/2OR6zIf"&gt;Git-Town&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bit.ly/37F8vu1"&gt;Bit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bit.ly/3boywik"&gt;GitHub CLI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bit.ly/3pEu8AJ"&gt;Git Graph&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bit.ly/3dBaUcZ"&gt;Git Lens&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’m not going to go into full detail on each, but check these out to help expedite your workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Challenge In Keeping Up To Date With Main
&lt;/h2&gt;

&lt;p&gt;I use what’s normally called &lt;code&gt;trunk-based&lt;/code&gt; development. This entails regularly moving commits from branches into the main branch, often rebasing while maintaining it in a functional state.&lt;/p&gt;

&lt;p&gt;I’ll create a feature branch, bug fix, or refactor branch and then merge this to &lt;code&gt;main&lt;/code&gt; as soon as functional.&lt;/p&gt;

&lt;p&gt;I prefer a rebase approach on my branches, and when many ci/fix type commits, to squash this into a single unit of work as the results of the PR. This can result in “merge hell” as you try rebase on a busy repo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter Git Town
&lt;/h2&gt;

&lt;p&gt;This tool solves so many of the basic workflow issues, that it’s become one of the most impactful tools to my daily work.&lt;/p&gt;

&lt;p&gt;Enable Aliases&lt;/p&gt;

&lt;p&gt;The examples that follow use &lt;code&gt;git sync&lt;/code&gt;, &lt;code&gt;git hack feat/new-feature&lt;/code&gt;, etc as examples because I’ve run the command &lt;code&gt;git-town alias true&lt;/code&gt; which enables the alias configuration for git town, reducing verbosity. Instead of &lt;code&gt;git town sync&lt;/code&gt;, you can run &lt;code&gt;git sync&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 1: Create a Branch for a New Unit of Work While You Are Already On Another Branch
&lt;/h3&gt;

&lt;p&gt;Normally this would require:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Stash/Push current work&lt;/li&gt;
&lt;li&gt;Checkout master&lt;/li&gt;
&lt;li&gt;Fetch latest and pull with rebase&lt;/li&gt;
&lt;li&gt;Resolve any conflicts from rebase&lt;/li&gt;
&lt;li&gt;Create the new branch from main&lt;/li&gt;
&lt;li&gt;Switch to the new branch&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With Git Town&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;git hack feat/new-feature&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Example 2: Sync Main
&lt;/h3&gt;

&lt;p&gt;The following steps would be performed by: &lt;code&gt;git sync&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[master] git fetch --prune --tags
[master] git add -A
[master] git stash
[master] git rebase origin/master
[master] git push --tags
[master] git stash pop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example 3: New Branch From Main
&lt;/h3&gt;

&lt;p&gt;Easy to quickly ensure you are up to date with remote and generate a new branch with your current uncommitted changes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[master] git fetch --prune --tags
[master] git add -A
[master] git stash
[master] git rebase origin/master
[master] git branch feat/demo-feature master
[master] git checkout feat/demo-feature
[feat/demo-feature] git stash pop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example 4: Quickly Create a PR While On A Branch for Seperate Set of Changes
&lt;/h3&gt;

&lt;p&gt;This workflow is far too tedious to do without tooling like this.&lt;/p&gt;

&lt;p&gt;Let’s say I’m on a branch doing some work, and then I recognize that another bug, doc improvements, or other change unrelated to my current work would be good to submit.&lt;/p&gt;

&lt;p&gt;With git town, it’s as simple as: &lt;code&gt;git town hack feat/improve-docs&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This pulls the latest, flips you over to the new branch, and sets you up to commit just the lines or files you need from all the pending changes that still show up. Commit those specific changes, sync, and you’ve now got an upstream branch with minimal effort that is also updated from main.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[feat/demo-feature] git fetch --prune --tags
[feat/demo-feature] git add -A
[feat/demo-feature] git stash
[feat/demo-feature] git checkout master
[master] git rebase origin/master
[master] git branch feat/demo-feature-2 master
[master] git checkout feat/demo-feature-2
[feat/demo-feature-2] git stash pop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example 5: Ship It
&lt;/h3&gt;

&lt;p&gt;When not using a PR-driven workflow, such as solo projects, then you can still branch and get your work over to main to keep a cleaner history with &lt;code&gt;git town ship&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This command ensures all the sync features are run, while then initiating a squash of your branch, allow you to edit the squash message, rebase merge this onto main, and finally clean-up the stale branch.&lt;/p&gt;

&lt;h3&gt;
  
  
  More Examples
&lt;/h3&gt;

&lt;p&gt;Check out the documentation from the creators: &lt;a href="https://bit.ly/3kjgsKy"&gt;Git Town Tutorials&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Other Cool Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Automatically prune stale branches after PR merge when syncing&lt;/li&gt;
&lt;li&gt;Handles perennial branches if you are using Git Flow methodology.&lt;/li&gt;
&lt;li&gt;Extensible for other git providers.&lt;/li&gt;
&lt;li&gt;Rename a local branch + remote branch in a single command&lt;/li&gt;
&lt;li&gt;Handles a lot of edge cases and failures&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wrap-Up
&lt;/h2&gt;

&lt;p&gt;When using git, leveraging some tooling like this can accelerate your workflow. I don’t think you need to be an expert in git to use this, as it helps simplify many workflows that are just too tedious to be diligent on when running manually.&lt;/p&gt;

&lt;p&gt;You can also do much of this with git aliases, but Git Town has a pretty robust feature-set with a testing framework in place, edge condition handling, and it’s fast. Consider using it you’d like to improve your git workflow while simplifying all the effort to do it right.&lt;/p&gt;

</description>
      <category>git</category>
    </item>
    <item>
      <title>Incremental and Consistent</title>
      <dc:creator>Sheldon</dc:creator>
      <pubDate>Sat, 13 Feb 2021 09:53:31 +0000</pubDate>
      <link>https://dev.to/sheldonhull/incremental-and-consistent-5gne</link>
      <guid>https://dev.to/sheldonhull/incremental-and-consistent-5gne</guid>
      <description>&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--d-BAHF_O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1042085119505227777/l3Xhlcse_normal.jpg" alt="Allen Holub profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Allen Holub
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        @allenholub
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ir1kO05j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      Saying that we do knowledge work but have no time for learning is like saying we do farm work but have no time for planting.
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      00:46 AM - 13 Feb 2021
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1360389911266820096" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fFnoeFxk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-reply-action-238fe0a37991706a6880ed13941c3efd6b371e4aefe288fe8e0db85250708bc4.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1360389911266820096" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k6dcrOn8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-retweet-action-632c83532a4e7de573c5c08dbb090ee18b348b13e2793175fea914827bc42046.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/like?tweet_id=1360389911266820096" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SRQc9lOp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-like-action-1ea89f4b87c7d37465b0eb78d51fcb7fe6c03a089805d7ea014ba71365be5171.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


&lt;p&gt;It's really hard to prioritize when life gets busy, but it's important that continued improvement is a priority.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.amazon.com/Great-Work-Performers-Less-Achieve/dp/1501179519"&gt;Great at Work: How Top Performers Do Less, Work Better, and Achieve More&lt;/a&gt; was a really interesting book.&lt;br&gt;
The fact that small incremental improvement done daily can make such a difference is pretty interesting.&lt;/p&gt;

&lt;p&gt;It's similar to Agile tenets in how to approach software design.&lt;br&gt;
Smaller iterations with rapid feedback is better than large isolated batches work delivered without regular feedback.&lt;/p&gt;

&lt;p&gt;If you find yourself saying, "But I don't have time" or "When I have some time" it might be indicative of a failure to grasp this.&lt;br&gt;
When I catch myself saying this I try to reword it and say "Whenever I make time for this" instead.&lt;/p&gt;

&lt;p&gt;You'll always have pressure on you.&lt;br&gt;
The further along in your career and life you go, the more pressure is likely to be on you.&lt;/p&gt;

&lt;p&gt;You have to "make" time for improvement and learning if it's a priority.&lt;/p&gt;

</description>
      <category>development</category>
      <category>learning</category>
    </item>
    <item>
      <title>Working With Powershell Objects to Create Yaml</title>
      <dc:creator>Sheldon</dc:creator>
      <pubDate>Tue, 09 Feb 2021 05:30:39 +0000</pubDate>
      <link>https://dev.to/sheldonhull/working-with-powershell-objects-to-create-yaml-2kp0</link>
      <guid>https://dev.to/sheldonhull/working-with-powershell-objects-to-create-yaml-2kp0</guid>
      <description>&lt;h2&gt;
  
  
  Who This Might Be For
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;PowerShellers wanting to know how to create json and yaml dynamically via &lt;code&gt;pscustomobject&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Anyone wanting to create configs like Datadog or other tools dynamically without the benefit of a configuration management tool.&lt;/li&gt;
&lt;li&gt;Anyone else wanting to fall asleep more quickly. (I can think of better material such as the Go spec docs, but hey, I can't argue with your good taste 😄)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  YAML
&lt;/h2&gt;

&lt;p&gt;It's readable.&lt;/p&gt;

&lt;p&gt;It's probably cost all of us hours when debugging yaml that's nested several layers and an errant whitespace got in.&lt;/p&gt;

&lt;p&gt;It's here to stay.&lt;/p&gt;

&lt;p&gt;I prefer it over JSON for readability, but I prefer JSON for programmability.&lt;/p&gt;

&lt;p&gt;Sometimes though, tooling uses yaml, and we need to be able to flip between both.&lt;/p&gt;

&lt;p&gt;Historically I've used &lt;code&gt;cfn-flip&lt;/code&gt; which is pretty great.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter yq
&lt;/h2&gt;

&lt;p&gt;The problem I have with using &lt;code&gt;cfn-flip&lt;/code&gt; is dependencies.&lt;br&gt;
It's a bit crazy to setup a docker image and then need to install a bunch of python setup tools to just get this one tool when it's all I need.&lt;/p&gt;

&lt;p&gt;I thought about building a quick &lt;code&gt;Go&lt;/code&gt; app to do this and give me the benefit of a single binary, as there is a pretty useful &lt;code&gt;yaml&lt;/code&gt; package already.&lt;br&gt;
Instead, I found a robust package that is cross-platform called &lt;code&gt;yq&lt;/code&gt; and it's my new go to. 🎉&lt;/p&gt;
&lt;h2&gt;
  
  
  Just plain works
&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://bit.ly/3pphpTb" rel="noopener noreferrer"&gt;The docs are great&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Reading &lt;code&gt;STDIN&lt;/code&gt; is a bit clunky, but not too bad, though I wish it would take more of a pipeline input approach natively.&lt;br&gt;
Instead of passing in &lt;code&gt;{"string":"value"} | yq&lt;/code&gt; it requires you to specify &lt;code&gt;stringinput | yq eval - --prettyPrint&lt;/code&gt; .&lt;br&gt;
Note the single hyphen after eval. This is what signifies that the input is &lt;code&gt;STDIN&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Dynamically Generate Some Configs
&lt;/h2&gt;

&lt;p&gt;I was working on some Datadog config generation for SQL Server, and found this tooling useful, especially on older Windows instances that didn't have the capability to run the nice module &lt;a href="http://bit.ly/3j4D94J" rel="noopener noreferrer"&gt;powershell-yaml&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here's how to use PowerShell objects to help generate a yaml configuration file on demand.&lt;/p&gt;
&lt;h3&gt;
  
  
  Install
&lt;/h3&gt;

&lt;p&gt;See install directions for linux/mac, as it's pretty straightforward.&lt;/p&gt;

&lt;p&gt;For windows, the chocolatey package was outdated as of the time of the article using the version 3.x.&lt;/p&gt;

&lt;p&gt;I used a PowerShell 4.0 compatible syntax here that should work on any instances with access to the web.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Net.ServicePointManager&lt;/span&gt;&lt;span class="p"&gt;]::&lt;/span&gt;&lt;span class="n"&gt;SecurityProtocol&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Net.SecurityProtocolType&lt;/span&gt;&lt;span class="p"&gt;]::&lt;/span&gt;&lt;span class="n"&gt;Tls12&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nx"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Test-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'C:\tools\yq.exe'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-PathType&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Leaf&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nv"&gt;$ProgressPreference&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'SilentlyContinue'&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;New-Item&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'C:\tools'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-ItemType&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Directory&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Force&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;Invoke-WebRequest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'https://github.com/mikefarah/yq/releases/download/v4.4.1/yq_windows_amd64.exe'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-OutFile&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'C:\tools\yq.exe'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-UseBasicParsing&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;Unblock-File&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'C:\tools\yq.exe'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Confirm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="bp"&gt;$false&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once this was downloaded, you could either make sure &lt;code&gt;C:\tools&lt;/code&gt; was in &lt;code&gt;PATH&lt;/code&gt; or just use the fully qualified path for our simple use case.&lt;/p&gt;

&lt;h3&gt;
  
  
  Get AWS Metadata
&lt;/h3&gt;

&lt;p&gt;In AWS, I parsed the metadata for the AccountID and InstanceID to generate a query to pull the Name tag dynamically.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;TIP: 💡 You must have the required permissions for the instance profile for this to work.&lt;br&gt;
This is not an instance level permission, so you'll want to add the required DescribeTags and ListInstances permissions for using a command such as &lt;code&gt;Get-EC2Tag&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Import-Module&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;AWSPowershell&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Verbose&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="bp"&gt;$false&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;$null&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# AWSPowerShell is the legacy module, but is provided already on most AWS instances&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$response&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Invoke-RestMethod&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Uri&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'http://169.254.169.254/latest/dynamic/instance-identity/document'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-TimeoutSec&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$AccountId&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AccountId&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pull Back EC2 Tags
&lt;/h3&gt;

&lt;p&gt;Now we can pull back the tag using an EC2 instance filter object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$filters&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;@(&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Amazon.EC2.Model.Filter&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="err"&gt;::new(&lt;/span&gt;&lt;span class="s1"&gt;'resource-id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$response&lt;/span&gt;&lt;span class="err"&gt;.InstanceId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nv"&gt;$tags&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Get-EC2Tag&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Filters&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$filters&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nv"&gt;$tagcollection&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$tags&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ForEach&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nv"&gt;$t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;$_&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pscustomobject&lt;/span&gt;&lt;span class="p"&gt;]@{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nx"&gt;Name&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$t&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nx"&gt;Value&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$t&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;Write-Host&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Tags For Instance: &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nv"&gt;$tagcollection&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Format-Table&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-AutoSize&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Wrap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Out-String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="bp"&gt;$Host&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$Tags&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetEnumerator&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Where&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;$_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Key&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-eq&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'Name'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToLower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nv"&gt;$SqlInstance&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;$Host&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Switch Things Up With A Switch
&lt;/h3&gt;

&lt;p&gt;The next step was to alias the instance.&lt;/p&gt;

&lt;p&gt;The better way to do this would be to use a tag that it reads, but for my quick ad-hoc use, this just let me specific an explicit alias to generate as a tag in the yaml. Again, try to use the Datadog tagging feature to do this automatically if possible.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;TIP: 💡 If you aren't familiar with PowerShell's switch statement, it's a nice little feature for making this evaluation easy to read.&lt;br&gt;
For the breadth of what this cool language feature can do, check this article out:&lt;br&gt;
&lt;a href="http://bit.ly/3pwnei0" rel="noopener noreferrer"&gt;Everything you ever wanted to know about the switch statement&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="kr"&gt;switch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$AccountId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s1"&gt;'12345'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$AWSAccountAlias&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'mydevenv'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$stage&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'qa'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s1"&gt;'12345'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$AWSAccountAlias&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'myprodenv'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$stage&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'prod'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="kr"&gt;throw&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Couldn't match a valid account number to give this an alias"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, preview the results of this Frankenstein.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Write-Host&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-ForegroundColor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Green&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"
&lt;/span&gt;&lt;span class="se"&gt;`$&lt;/span&gt;&lt;span class="s2"&gt;HostName        = &lt;/span&gt;&lt;span class="bp"&gt;$Host&lt;/span&gt;&lt;span class="s2"&gt;Name
&lt;/span&gt;&lt;span class="se"&gt;`$&lt;/span&gt;&lt;span class="s2"&gt;SqlInstance     = &lt;/span&gt;&lt;span class="nv"&gt;$SqlInstance&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;span class="se"&gt;`$&lt;/span&gt;&lt;span class="s2"&gt;AWSAccountAlias = &lt;/span&gt;&lt;span class="nv"&gt;$AWSAccountAlias&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;span class="se"&gt;`$&lt;/span&gt;&lt;span class="s2"&gt;stage           = &lt;/span&gt;&lt;span class="nv"&gt;$stage&lt;/span&gt;&lt;span class="s2"&gt;
 "&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Ready To Generate Some Yaml Magic
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$TargetConfig&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Join-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;ENV&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;ProgramData&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'Datadog/conf.d/windows_service.d/conf.yaml'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$Services&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pscustomobject&lt;/span&gt;&lt;span class="p"&gt;]@{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s1"&gt;'instances'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;@(&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ordered&lt;/span&gt;&lt;span class="p"&gt;]@{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s1"&gt;'services'&lt;/span&gt;&lt;span class="w"&gt;                   &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;@(&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s1"&gt;'SQLSERVERAGENT'&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s1"&gt;'MSSQLSERVER'&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s1"&gt;'SQLSERVERAGENT'&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s1"&gt;'disable_legacy_service_tag'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;$true&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s1"&gt;'tags'&lt;/span&gt;&lt;span class="w"&gt;                       &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;@(&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"aws_account_alias:&lt;/span&gt;&lt;span class="nv"&gt;$AWSAccountAlias&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"sql_instance:&lt;/span&gt;&lt;span class="nv"&gt;$SqlInstance&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"stage:&lt;/span&gt;&lt;span class="nv"&gt;$stage&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nv"&gt;$Services&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ConvertTo-Json&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Depth&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;100&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="s1"&gt;'C:\tools\yq.exe'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;eval&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--prettyPrint&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Out-File&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$TargetConfig&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Encoding&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;UTF8&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This would produce a nice json output like this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.sheldonhull.com%2Fimages%2F2021-02-08-yaml-config-example.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.sheldonhull.com%2Fimages%2F2021-02-08-yaml-config-example.png" alt="Example config image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  One More Complex Example
&lt;/h3&gt;

&lt;p&gt;Start with creating an empty array and some variables to work with.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$UserName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'TacoBear'&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$Password&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'YouReallyThinkI''dPostThis?Funny'&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$TargetConfig&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Join-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;ENV&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;ProgramData&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'Datadog/conf.d/sqlserver.d/conf.yaml'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$Queries&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;@()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next include the generic Datadog collector definition.&lt;/p&gt;

&lt;p&gt;This is straight outta their &lt;a href="http://bit.ly/3cisxgY" rel="noopener noreferrer"&gt;Github repo&lt;/a&gt; with the benefit of some tagging.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$Queries&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ordered&lt;/span&gt;&lt;span class="p"&gt;]@{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s1"&gt;'host'&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'tcp:localhost,1433'&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s1"&gt;'username'&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$UserName&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s1"&gt;'password'&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$Password&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s1"&gt;'connector'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'adodbapi'&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s1"&gt;'driver'&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'SQL Server'&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s1"&gt;'database'&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'master'&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s1"&gt;'tags'&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;@(&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"aws_account_alias:&lt;/span&gt;&lt;span class="nv"&gt;$AWSAccountAlias&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"sql_instance:&lt;/span&gt;&lt;span class="nv"&gt;$SqlInstance&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"stage:&lt;/span&gt;&lt;span class="nv"&gt;$stage&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;TIP: 💡 Using &lt;code&gt;+=&lt;/code&gt; is a bit of an anti-pattern for high performance PowerShell, but it works great for something like this that's ad-hoc and needs to be simple.&lt;br&gt;
For high performance needs, try using something like &lt;code&gt;$list = [Systems.Collections.Generic.List[pscustomobject]]:new()&lt;/code&gt; for example.&lt;br&gt;
This can then allow you to use the &lt;code&gt;$list.Add([pscustomobject]@{}&lt;/code&gt; to add items.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A bit more complex, but very powerful and performance, with the benefit of stronger data typing.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This one is a good example of the custom query format that Datadog supports, but honestly I found pretty confusing in their docs until I bumbled my way through a few iterations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$Queries&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ordered&lt;/span&gt;&lt;span class="p"&gt;]@{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="c"&gt;# description: Not Used by Datadog, but helpful to reading the yaml, be kind to those folks!&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="w"&gt;             &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'Get Count of Databases on Server'&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s1"&gt;'host'&lt;/span&gt;&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'tcp:localhost,1433'&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s1"&gt;'username'&lt;/span&gt;&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$UserName&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s1"&gt;'database'&lt;/span&gt;&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'master'&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s1"&gt;'password'&lt;/span&gt;&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$Password&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s1"&gt;'connector'&lt;/span&gt;&lt;span class="w"&gt;               &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'adodbapi'&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s1"&gt;'driver'&lt;/span&gt;&lt;span class="w"&gt;                  &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'SQL Server'&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s1"&gt;'min_collection_interval'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;timespan&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="err"&gt;::&lt;/span&gt;&lt;span class="nx"&gt;FromHours&lt;/span&gt;&lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;TotalSeconds&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s1"&gt;'command_timeout'&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="s1"&gt;'custom_queries'&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;@(&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ordered&lt;/span&gt;&lt;span class="p"&gt;]@{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s1"&gt;'query'&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"select count(name) from sys.databases as d where d.Name not in ('master', 'msdb', 'model', 'tempdb')"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s1"&gt;'columns'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;@(&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ordered&lt;/span&gt;&lt;span class="p"&gt;]@{&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'instance.database_count'&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'gauge'&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="s1"&gt;'tags'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;@(&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="s2"&gt;"aws_account_alias:&lt;/span&gt;&lt;span class="nv"&gt;$AWSAccountAlias&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="s2"&gt;"sql_instance:&lt;/span&gt;&lt;span class="nv"&gt;$SqlInstance&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="s2"&gt;"stage:&lt;/span&gt;&lt;span class="nv"&gt;$stage&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let me do a quick breakdown, in case you aren't as familiar with this type of syntax in PowerShell.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;$Queries +=&lt;/code&gt; takes whatever existing object we have and replaces it with the current object + the new object. This is why it's not performant for large scale work as it's basically creating a whole new copy of the collection with your new addition.&lt;/li&gt;
&lt;li&gt;Next, I'm using &lt;code&gt;[ordered]&lt;/code&gt; instead of &lt;code&gt;[pscustomobject]&lt;/code&gt; which in effect does the same thing, but ensures I'm not having all my properties randomly sorted each time. Makes things a little easier to review. This is a shorthand syntax for what would be a much longer tedious process using &lt;code&gt;New-Object&lt;/code&gt; and &lt;code&gt;Add-Member&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Custom queries is a list, so I cast it with &lt;code&gt;@()&lt;/code&gt; format, which tells PowerShell to expect a list. This helps json/yaml conversion be correct even if you have just a single entry. You can be more explicit if you want, like &lt;code&gt;[pscustomobject[]]@()&lt;/code&gt; but since PowerShell ignores you mostly on trying to be type specific, it's not worth it. Don't try to make PowerShell be Go or C#. 😁&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Flip To Yaml
&lt;/h3&gt;

&lt;p&gt;Ok, we have an object list, now we need to flip this to yaml.&lt;/p&gt;

&lt;p&gt;It's not as easy as &lt;code&gt;$Queries | yq&lt;/code&gt; because of the difference in paradigm with .NET.&lt;/p&gt;

&lt;p&gt;We are working with a structured object.&lt;/p&gt;

&lt;p&gt;Just look at &lt;code&gt;$Queries | Get-Member&lt;/code&gt; and you'll probably get: &lt;code&gt;TypeName: System.Collections.Specialized.OrderedDictionary.&lt;/code&gt; The difference is that Go/Linux paradigm is focused on text, not objects. With &lt;code&gt;powershell-yaml&lt;/code&gt; module you can run &lt;code&gt;ConvertTo-Yaml $Queries&lt;/code&gt; and it will work as it will handle the object transformation.&lt;/p&gt;

&lt;p&gt;However, we can actually get there with PowerShell, just need to think of a text focused paradigm instead. This is actually pretty easy using &lt;code&gt;Converto-Json&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$SqlConfig&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ordered&lt;/span&gt;&lt;span class="p"&gt;]@{&lt;/span&gt;&lt;span class="s1"&gt;'instances'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$Queries&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$SqlConfig&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ConvertTo-Json&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Depth&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;100&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="s1"&gt;'C:\tools\yq.exe'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;eval&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--prettyPrint&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Out-File&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$TargetConfig&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Encoding&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;UTF8&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This takes the object, converts to json uses the provided cmdlet from PowerShell that knows how to properly take the object and all the nested properties and magically split to &lt;code&gt;JSON&lt;/code&gt;.  Pass this into the &lt;code&gt;yq&lt;/code&gt; executable, and behold, the magic is done.&lt;/p&gt;

&lt;p&gt;You should have a nicely formatted yaml configuration file for Datadog.&lt;/p&gt;

&lt;p&gt;If not, the dog will yip and complain with a bunch of red text in the log.&lt;/p&gt;

&lt;h3&gt;
  
  
  Debug Helper
&lt;/h3&gt;

&lt;p&gt;Use this on the remote instance to simplify some debugging, or even connect via SSM directly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;ProgramFiles&lt;/span&gt;&lt;span class="s2"&gt;\Datadog\Datadog Agent\bin\agent.exe"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;stopservice&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;ProgramFiles&lt;/span&gt;&lt;span class="s2"&gt;\Datadog\Datadog Agent\bin\agent.exe"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;start-service&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;#Stream Logs without gui if remote session using:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Get-Content&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'C:\ProgramData\Datadog\logs\agent.log'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Tail&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Wait&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# interactive debugging and viewing of console&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# &amp;amp; "$env:ProgramFiles\Datadog\Datadog Agent\bin\agent.exe" launch-gui&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Wrap Up
&lt;/h2&gt;

&lt;p&gt;Ideally, use Chef, Ansible, Saltstack, DSC, or another tool to do this. However, sometimes you just need some flexible options for generating this type of content dynamically. Hopefully, you'll find this useful in your PowerShell magician journey and save some time.&lt;/p&gt;

&lt;p&gt;I've already found it useful in flipping json content for various tools back and forth. 🎉&lt;/p&gt;

&lt;p&gt;A few scenarios that tooling like yq might prove useful could be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;convert simple query results from json to yaml and store in git as config&lt;/li&gt;
&lt;li&gt;Flip an SSM Json doc to yaml&lt;/li&gt;
&lt;li&gt;Review a complex json doc by flipping to yaml for more readable syntax&lt;/li&gt;
&lt;li&gt;Confusing co-workers by flipping all their cloudformation from yaml to json or yaml from json. (If you take random advice like this and apply, you probably deserve the aftermath this would bring 🤣.)&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>powershell</category>
      <category>devops</category>
      <category>datadog</category>
    </item>
    <item>
      <title>Nativefier</title>
      <dc:creator>Sheldon</dc:creator>
      <pubDate>Mon, 25 Jan 2021 22:19:41 +0000</pubDate>
      <link>https://dev.to/sheldonhull/nativefier-4foc</link>
      <guid>https://dev.to/sheldonhull/nativefier-4foc</guid>
      <description>&lt;p&gt;Ran across this app, and thought was kinda cool. I've had some issues with Chrome apps showing up correctly in certain macOS windows managers to switch context quickly.&lt;/p&gt;

&lt;p&gt;Using this tool, you can generate a standalone electron app bundle to run a webpage in as it's own dedicated window.&lt;/p&gt;

&lt;p&gt;It's cross-platform.&lt;/p&gt;

&lt;p&gt;For a site like Azure DevOps, you can run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$MYORG&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'foo'&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$MYPROJECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'bar'&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$BOARDNAME&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'bored'&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;nativefier&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;https://dev.azure.com/&lt;/span&gt;&lt;span class="nv"&gt;$MYORG&lt;/span&gt;&lt;span class="nx"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;$MYPROJECT&lt;/span&gt;&lt;span class="nx"&gt;/_boards/board/t/&lt;/span&gt;&lt;span class="nv"&gt;$BOARDNAME&lt;/span&gt;&lt;span class="nx"&gt;/Backlog&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;20items/&lt;/span&gt;&lt;span class="nf"&gt;?&lt;/span&gt;&lt;span class="nx"&gt;fullScreen&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;~/&lt;/span&gt;&lt;span class="nv"&gt;$BOARDNAME&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If redirects for permissions occur due to external links opening, you might have to open the application bundle and edit the url mapping. &lt;a href="https://github.com/jiahaog/nativefier/issues/706"&gt;GitHub Issue #706&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/Users/$(whoami)/$BOARDNAME/APP-darwin-x64/$BOARDNAME.app/Contents/Resources/app/nativefier.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ensure your external urls match the redirect paths that you need such as below. I included the standard oauth redirect locations that Google, Azure DevOps, and Microsoft uses. Add your own such as github to this to have those links open inside the app and not in a new window that fails to recieve the postback.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"internalUrls"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"(._?contacts&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;google&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;com._?|._?dev.azure.com_?|._?microsoft.com_?|._?login.microsoftonline.com_?|._?azure.com_?|._?vssps.visualstudio.com._?)"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>cooltools</category>
      <category>tech</category>
      <category>macos</category>
    </item>
    <item>
      <title>Go R1 Day 27</title>
      <dc:creator>Sheldon</dc:creator>
      <pubDate>Fri, 22 Jan 2021 21:54:21 +0000</pubDate>
      <link>https://dev.to/sheldonhull/go-r1-day-27-8dk</link>
      <guid>https://dev.to/sheldonhull/go-r1-day-27-8dk</guid>
      <description>&lt;h2&gt;
  
  
  progress
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Iterated through AWS SDK v1 S3 buckets to process IAM policy permissions.&lt;/li&gt;
&lt;li&gt;Unmarshaled policy doc into struct using &lt;code&gt;Json-To-Struct&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://mholt.github.io/json-to-go/"&gt;JSON-to-Go&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>tech</category>
      <category>development</category>
      <category>100daysofcode</category>
      <category>go</category>
    </item>
    <item>
      <title>Github Pages Now Supports Private Pages</title>
      <dc:creator>Sheldon</dc:creator>
      <pubDate>Fri, 22 Jan 2021 02:07:36 +0000</pubDate>
      <link>https://dev.to/sheldonhull/github-pages-now-supports-private-pages-2hib</link>
      <guid>https://dev.to/sheldonhull/github-pages-now-supports-private-pages-2hib</guid>
      <description>&lt;p&gt;I'm a huge static site fan (lookup jamstack).&lt;/p&gt;

&lt;p&gt;What I've historically had a problem with was hosting. For public pages, it's great.&lt;/p&gt;

&lt;p&gt;For private internal docs, it's been problematic. It's more servers and access control to manage if you want something for a specific group inside a company to access.&lt;/p&gt;

&lt;p&gt;This new update is a big deal for those that want to provide an internal hugo, jekyll, mkdocs, or other static generate based documentation site for their team.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://bit.ly/2MdUeg9"&gt;Access control for GitHub Pages - GitHub Changelog&lt;/a&gt;&lt;/p&gt;

</description>
      <category>tech</category>
      <category>development</category>
      <category>microblog</category>
    </item>
    <item>
      <title>Ensuring Profile Environment Variables Available to Intellij</title>
      <dc:creator>Sheldon</dc:creator>
      <pubDate>Wed, 20 Jan 2021 23:05:12 +0000</pubDate>
      <link>https://dev.to/sheldonhull/ensuring-profile-environment-variables-available-to-intellij-2pp</link>
      <guid>https://dev.to/sheldonhull/ensuring-profile-environment-variables-available-to-intellij-2pp</guid>
      <description>&lt;p&gt;Open IntelliJ via terminal: &lt;code&gt;open "/Users/$(whoami)/Applications/JetBrains Toolbox/IntelliJ IDEA Ultimate.app"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This will ensure your &lt;code&gt;.profile&lt;/code&gt;, &lt;code&gt;.bashrc&lt;/code&gt;, and other profile settings that might be loading some default environment variables are available to your IDE. For macOS, you'd have to set in the &lt;code&gt;environment.plist&lt;/code&gt; otherwise to ensure they are available to a normal application.&lt;/p&gt;

&lt;p&gt;ref: &lt;a href="http://bit.ly/3p3BgHy"&gt;OSX shell environment variables - IDEs Support (IntelliJ Platform) | JetBrains&lt;/a&gt;&lt;/p&gt;

</description>
      <category>tech</category>
      <category>development</category>
      <category>microblog</category>
      <category>macos</category>
    </item>
    <item>
      <title>Create an S3 Lifecycle Policy with PowerShell</title>
      <dc:creator>Sheldon</dc:creator>
      <pubDate>Tue, 19 Jan 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/sheldonhull/create-an-s3-lifecycle-policy-with-powershell-57hd</link>
      <guid>https://dev.to/sheldonhull/create-an-s3-lifecycle-policy-with-powershell-57hd</guid>
      <description>&lt;p&gt;First, I’m a big believer in doing infrastructure as code.&lt;/p&gt;

&lt;p&gt;Using the AWS SDK with any library is great, but for things like S3 I’d highly recommend you use a Terraform module such as &lt;a href="https://registry.terraform.io/modules/cloudposse/s3-bucket/aws/latest"&gt;Cloudposse terraform-aws-s3-bucket module&lt;/a&gt;. Everything Cloudposse produces has great quality, flexibility with naming conventions, and more.&lt;/p&gt;

&lt;p&gt;Now that this disclaimer is out of the way, I’ve run into scenarios where you can have a bucket with a large amount of data such as databases which would be good to do some cleanup on before you migrate to newly managed backups.&lt;/p&gt;

&lt;p&gt;In my case, I’ve run into 50TB of old backups due to tooling issues that prevented cleanup from being successful. The backup tooling stored a sqlite database in one subdirectory and in another directory the actual backups.&lt;/p&gt;

&lt;p&gt;I preferred at this point to only perform the lifecycle cleanup on the backup files, while leaving the sqlite file alone. (side note: i always feel strange typing sqlite, like I’m skipping an l 😁).&lt;/p&gt;

&lt;p&gt;Here’s an example of how to do this from the AWS PowerShell docs.&lt;/p&gt;

&lt;p&gt;I modified this example to support providing multiple key prefixes. What wasn’t quite clear when I did this the need to create the entire lifecycle policy collection as a single object and pass this to the command.&lt;/p&gt;

&lt;p&gt;If you try to run a loop and create one lifecycle policy for each &lt;code&gt;Write-S3LifecycleConfiguration&lt;/code&gt; command, it only kept what last ran. Instead, ensure you create the entire object as shown in the example, and then you’ll be able to have multiple lifecycle policies get attached to your bucket.&lt;/p&gt;

&lt;p&gt;Good luck!&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
 #tech #development #aws #powershell #devops

</description>
    </item>
    <item>
      <title>Leverage Renovate for Easy Dependency Updates</title>
      <dc:creator>Sheldon</dc:creator>
      <pubDate>Thu, 14 Jan 2021 02:42:20 +0000</pubDate>
      <link>https://dev.to/sheldonhull/leverage-renovate-for-easy-dependency-updates-2i1</link>
      <guid>https://dev.to/sheldonhull/leverage-renovate-for-easy-dependency-updates-2i1</guid>
      <description>&lt;p&gt;Renovate is a great tool to know about. For Go, you can keep modules updated automatically, but still leverage a pull request review process to allow automated checks to run before allowing the update.&lt;/p&gt;

&lt;p&gt;This is particularly useful with Terraform dependencies, which I consider notoriously difficult to keep updated. Instead of needing to use ranges for modules, you can start specifying exact versions and this GitHub app will automatically check for updates periodically and submit version bumps.&lt;/p&gt;

&lt;p&gt;Why? You can have a Terraform plan previewed and checked for any errors on a new version update with no work. This means your blast radius on updates would be reduced as you are staying up to date and previewing each update as it's available.&lt;/p&gt;

&lt;p&gt;No more 5 months of updates and figuring out what went wrong 😁&lt;/p&gt;

&lt;p&gt;Here's an example json config that shows how to allow automerging, while respecting minor/major version updates not enabling automerge.&lt;/p&gt;

&lt;p&gt;Note that you'd want to install the auto-approver app they document in the marketplace if you have pull request reviews required.&lt;/p&gt;

&lt;p&gt;In addition, if you use &lt;code&gt;CODEOWNERS&lt;/code&gt; file, this will still block automerge. Consider removing that if you aren't really leveraging it.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


</description>
      <category>ci</category>
      <category>automation</category>
      <category>githubactions</category>
    </item>
    <item>
      <title>Go R1 Day 26</title>
      <dc:creator>Sheldon</dc:creator>
      <pubDate>Wed, 13 Jan 2021 03:25:48 +0000</pubDate>
      <link>https://dev.to/sheldonhull/go-r1-day-26-4ie9</link>
      <guid>https://dev.to/sheldonhull/go-r1-day-26-4ie9</guid>
      <description>&lt;h2&gt;
  
  
  Progress
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Evaluated gorm usage best practices with Slack Gopher community.&lt;/li&gt;
&lt;li&gt;Obtained a great example to get me started on go routine and channels usage with multi-database queries.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>tech</category>
      <category>development</category>
      <category>100daysofcode</category>
      <category>go</category>
    </item>
  </channel>
</rss>
