<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Brian Bunke</title>
    <description>...And You Will Know Me by the Trail of Documentation</description>
    <link>https://brianbunke.github.io/</link>
    <atom:link href="https://brianbunke.github.io/feed.xml" rel="self" type="application/rss+xml" />
    <pubDate>Tue, 26 May 2026 18:38:04 +0000</pubDate>
    <lastBuildDate>Tue, 26 May 2026 18:38:04 +0000</lastBuildDate>
    <generator>Jekyll v3.10.0</generator>
    
      <item>
        <title>Parental Controls v1 in 2026</title>
        <description>&lt;h2 id=&quot;context&quot;&gt;Context&lt;/h2&gt;

&lt;p&gt;It’s 2026 and this article currently applies to 10- and 8-year-old boys.&lt;/p&gt;

&lt;p&gt;My kids have a &lt;a href=&quot;https://www.intel.com/content/www/us/en/products/sku/83255/intel-nuc-kit-nuc5i5ryh/specifications.html&quot;&gt;2015 Intel NUC&lt;/a&gt; in their room. Years ago we got tired of them asking to borrow our phones to play music while cleaning up. I liked the idea of giving them music-on-demand and learning to operate a mouse &amp;amp; keyboard setup. They have a Spotify account on our family plan with explicit content disabled. (Spotify parent rant at end of article.)&lt;/p&gt;

&lt;p&gt;The NUC had &lt;a href=&quot;https://ubuntu.com/download/desktop&quot;&gt;Ubuntu Desktop&lt;/a&gt; installed, but the hard drive died this year, and I switched to &lt;a href=&quot;https://www.linuxmint.com&quot;&gt;Linux Mint&lt;/a&gt; on the NVMe replacement. It has Spotify and Firefox installed with the home page set to their school’s &lt;a href=&quot;https://sunnyland.bellinghamschools.org/academics/computer-science/&quot;&gt;computer science&lt;/a&gt; page. Link included for resource ideas; the current fun is code.org’s &lt;a href=&quot;https://code.org/en-US/hour-of-code/dance&quot;&gt;Dance Party&lt;/a&gt; using Scratch-style code blocks.&lt;/p&gt;

&lt;p&gt;We have left it with no parental controls and passive monitoring for years – the deviant behavior has just been searching for fart songs.&lt;/p&gt;

&lt;p&gt;My kids know I can use my phone to look up answers to their questions, and recently my oldest has asked to use my computer to search for answers while I’ve been in the room. He just turned 10 and almost immediately discovered he can do the same on his computer, so I’m refreshing on digital parenting in 2026.&lt;/p&gt;

&lt;h2 id=&quot;intent&quot;&gt;Intent&lt;/h2&gt;

&lt;p&gt;If you’ve read &lt;a href=&quot;https://www.anxiousgeneration.com/book&quot;&gt;The Anxious Generation&lt;/a&gt;, this will be a familiar exercise. Basically, how can we impart freedom and digital literacy while minimizing exposure to addicting screen time and inappropriate online content?&lt;/p&gt;

&lt;p&gt;For my part, I prioritize self-sufficiency over most other competing interests. (This tends to carry over as a work ideology as well.) Our job as parents is to teach kids how to learn and thrive in this world without us.&lt;/p&gt;

&lt;p&gt;As the book harps on, an unsupervised child online is far more likely to end worse vs. that same child roaming the neighborhood unsupervised, so we need to draw and monitor some boundaries.&lt;/p&gt;

&lt;p&gt;There is a lot of worry these days that exposing how you parent incurs silent judgment from other parents. I’m (over-)confident enough with our balance to feel comfortable sharing our current philosophy and strategy. Hopefully it also spurs conversations that help me learn from others.&lt;/p&gt;

&lt;h2 id=&quot;new-actions&quot;&gt;New Actions&lt;/h2&gt;

&lt;p&gt;Here are my first steps. As usual with blogging, I hope this helps you, but I’m also writing this as memory for future me.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Mint OS user account is standard. Guest sessions are disabled. Admin account is parents-only.
    &lt;ul&gt;
      &lt;li&gt;Annoying for applying regular updates, but a necessary evil for now.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Firefox settings. No real parental controls here, but we’ll do our best.
    &lt;ol&gt;
      &lt;li&gt;Disable all suggestions and recommendations.&lt;/li&gt;
      &lt;li&gt;Disable all AI.&lt;/li&gt;
      &lt;li&gt;Default to DuckDuckGo for searches.&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://blog.cloudflare.com/introducing-1-1-1-1-for-families/&quot;&gt;Cloudflare Families&lt;/a&gt; – block malware and adult content at DNS.
    &lt;ul&gt;
      &lt;li&gt;They provide &lt;a href=&quot;https://malware.testcategory.com&quot;&gt;malware.testcategory.com&lt;/a&gt; and &lt;a href=&quot;https://nudity.testcategory.com&quot;&gt;nudity.testcategory.com&lt;/a&gt; to help verify implementation.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://store.ui.com/us/en/products/udm-pro&quot;&gt;Ubiquiti UDM Pro&lt;/a&gt;
    &lt;ol&gt;
      &lt;li&gt;Create Kids network with static DNS servers &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1.1.1.3&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1.0.0.3&lt;/code&gt;.&lt;/li&gt;
      &lt;li&gt;Create Kids wifi tied to that network. (&lt;a href=&quot;https://help.ui.com/hc/en-us/articles/29887064407319-Using-PPSK-RADIUS-for-Multiple-VLANs-On-an-SSID-in-UniFi-Network?utm_source=chatgpt.com&quot;&gt;Private Pre-Shared Keys&lt;/a&gt; makes this very clean.)&lt;/li&gt;
      &lt;li&gt;Create Kids content filter and apply it to the Kids network.
        &lt;ul&gt;
          &lt;li&gt;You can ad block and force a couple safe search settings here.&lt;/li&gt;
          &lt;li&gt;The Enhanced filter redundantly leverages Cloudflare, so I left it on Basic.&lt;/li&gt;
          &lt;li&gt;Explicit allow/block lists; prefer to solve here vs. a browser extension.
            &lt;ul&gt;
              &lt;li&gt;youtube.com – YouTube has been a strict “parental supervision only” zone for 10 years, and I’m not ready to change yet.&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;next-steps&quot;&gt;Next Steps&lt;/h2&gt;

&lt;p&gt;My explicit block list is woefully insufficient/naive/etc. This whack-a-mole is a game I will lose and would rather not play. When I’m ready to unblock YouTube and whatever else has joined it, we’ll have more conversations with the kids to convey our intents, goals, and boundaries.&lt;/p&gt;

&lt;p&gt;I will probably set up a daily/weekly digest of browser history to my email for passive review. This should be the most fun technical problem to solve. If that happens, I’ll want to disable it again when they’re older to give some privacy back.&lt;/p&gt;

&lt;p&gt;I haven’t added screen-time limits. There are various ways to solve this, but it’s not yet necessary as we handle this in-person.&lt;/p&gt;

&lt;p&gt;There are obvious workarounds for everything here; part of learning computers as a teenager is being motivated to clear various hurdles. But again, they’re 10 and 8, not doing this yet, and we’re physically close enough to monitor the situation.&lt;/p&gt;

&lt;h2 id=&quot;spotify-rant&quot;&gt;Spotify Rant&lt;/h2&gt;

&lt;p&gt;Spotify added videos and visuals and did not immediately provide controls for blocking them on accounts. There are finally controls now under “Videos and Canvas” to disable this.&lt;/p&gt;

&lt;p&gt;One checkbox for “explicit content” was a pathetic lack of control for a long time. Spotify recognized this and added &lt;a href=&quot;https://support.spotify.com/us/article/managed-accounts/&quot;&gt;Managed Accounts&lt;/a&gt;…but you can only auth into a managed account on a mobile app. They do not currently provide a way for managed accounts to log into their desktop applications. Of course, you wouldn’t admit to any known limitations in the article – parents should create the account and then spend 20 minutes wondering how something so easy is very much not.&lt;/p&gt;

&lt;p&gt;But for all the complaining I’ll happily give you about Spotify…it ain’t YouTube.&lt;/p&gt;

</description>
        <pubDate>Tue, 26 May 2026 08:00:00 +0000</pubDate>
        <link>https://brianbunke.github.io/blog/2026/05/26/parental-controls-v1/</link>
        <guid isPermaLink="true">https://brianbunke.github.io/blog/2026/05/26/parental-controls-v1/</guid>
        
        <category>family</category>
        
        <category>parenting</category>
        
        
        <category>blog</category>
        
      </item>
    
      <item>
        <title>My Hallway is Red During Teams Calls</title>
        <description>&lt;p&gt;Not blogging for over a year has really changed my outlook on titling blog posts.&lt;/p&gt;

&lt;h2 id=&quot;tldr&quot;&gt;tl;dr&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/brianbunke/TeamsStatus&quot;&gt;https://github.com/brianbunke/TeamsStatus&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/teams-hallway.jpg&quot; alt=&quot;teams-hallway&quot; /&gt;
&lt;img src=&quot;/images/teams-seinfeld.jpg&quot; alt=&quot;teams-seinfeld&quot; /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Why?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So my family knows the answer before they walk down the hall and open the door.&lt;/p&gt;

&lt;p&gt;Also because my wife linked &lt;a href=&quot;https://www.amazon.com/HONWELL-Control-Operated-Wireless-Colors-Dimmable/dp/B07B2YLY6D/&quot;&gt;lights with an infrared remote&lt;/a&gt; as a suggestion, and that was the final push I needed to prioritize solving this automagically.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 class=&quot;no_toc&quot; id=&quot;table-of-contents&quot;&gt;Table of Contents&lt;/h2&gt;

&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#tldr&quot; id=&quot;markdown-toc-tldr&quot;&gt;tl;dr&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#prerequisites&quot; id=&quot;markdown-toc-prerequisites&quot;&gt;Prerequisites&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#detect-teams-status&quot; id=&quot;markdown-toc-detect-teams-status&quot;&gt;Detect Teams Status&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#locally-why&quot; id=&quot;markdown-toc-locally-why&quot;&gt;Locally? Why?&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#teams-code&quot; id=&quot;markdown-toc-teams-code&quot;&gt;Teams Code&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#newactivity&quot; id=&quot;markdown-toc-newactivity&quot;&gt;NewActivity&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#red-the-light&quot; id=&quot;markdown-toc-red-the-light&quot;&gt;Red the Light&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#backstory--why-kasa&quot; id=&quot;markdown-toc-backstory--why-kasa&quot;&gt;Backstory / Why Kasa&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#kasa-code&quot; id=&quot;markdown-toc-kasa-code&quot;&gt;Kasa Code&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#kasa-app&quot; id=&quot;markdown-toc-kasa-app&quot;&gt;Kasa App&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#red-the-slack&quot; id=&quot;markdown-toc-red-the-slack&quot;&gt;Red the Slack&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#new-slack-app-and-key&quot; id=&quot;markdown-toc-new-slack-app-and-key&quot;&gt;New Slack app and key&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#slack-code&quot; id=&quot;markdown-toc-slack-code&quot;&gt;Slack Code&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#task-scheduler&quot; id=&quot;markdown-toc-task-scheduler&quot;&gt;Task Scheduler&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#in-conclusion&quot; id=&quot;markdown-toc-in-conclusion&quot;&gt;In Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;prerequisites&quot;&gt;Prerequisites&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;PowerShell and Python
    &lt;ul&gt;
      &lt;li&gt;Walkthrough assumes Windows&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Microsoft Teams is where you take most/all your video calls&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.amazon.com/alexa-smart-light-bulb-wifi/dp/B08TB8QBB1&quot;&gt;Kasa KL125&lt;/a&gt; smart bulb on firmware version 1.2
    &lt;ul&gt;
      &lt;li&gt;I was told 2.0 breaks the local API. (Which has always been undocumented, but previously reverse engineered by some very fine souls.)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Slack (optional, but I solved for it before I had a bulb)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;detect-teams-status&quot;&gt;Detect Teams Status&lt;/h2&gt;

&lt;h3 id=&quot;locally-why&quot;&gt;Locally? Why?&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Because, quick and dirty as it is, it works&lt;/li&gt;
  &lt;li&gt;Because it doesn’t ask you to hold admin rights or learn a new cloud thing&lt;/li&gt;
  &lt;li&gt;Because I couldn’t figure out querying Teams presence in Microsoft Graph in an unattended fashion&lt;/li&gt;
  &lt;li&gt;Because my Teams resides in Government Cloud, which is constant “Am I doing this wrong, or is this just silently absent in GCC High?”&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;teams-code&quot;&gt;Teams Code&lt;/h3&gt;

&lt;p&gt;I spent two minutes trying to rediscover the Github link where I learned about the local log parsing, but failed. Honestly sorry I can’t link and give you credit! :(&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;nv&quot;&gt;$Time&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-Date&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# Local Teams log FTW&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$StatusLog&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-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;s2&quot;&gt;&quot;&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;APPDATA&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;\Microsoft\Teams\logs.txt&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Tail&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;1000&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;Select-String&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Pattern&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;StatusIndicatorStateService: Added&apos;&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;Select-Object&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Last&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;# RegEx all the things&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;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$StatusLog&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-match&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;(.*?)\sGMT.*StatusIndicatorStateService:\sAdded\s(.*)\s\(.*:\s(.*)\s-\&amp;gt;\s(.*)\)&apos;&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;$LogTime&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-Date&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;$Matches&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;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$TeamsStatus&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;$Matches&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;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$StatusOld&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;$Matches&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&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;$StatusNew&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;$Matches&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&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;c&quot;&gt;# Quit if there is no new log entry&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# &quot;NewActivity&quot; overwrites OnThePhone/Presenting, but could happen in or out of a call&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# Ignore NewActivity and continue using the prior status instead&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;$Time&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddMinutes&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;o&quot;&gt;-gt&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$LogTime&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-or&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$TeamsStatus&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;s1&quot;&gt;&apos;NewActivity&apos;&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;exit&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;Yep, &lt;a href=&quot;https://twitter.com/brianbunke/status/1247369403840073728&quot;&gt;log parsing with RegEx&lt;/a&gt;! By remaining on this site you consent to the use of RegEx and agree that &lt;a href=&quot;https://regex101.com&quot;&gt;regex101.com&lt;/a&gt; owns your binding arbitration or you know whatever&lt;/p&gt;

&lt;h3 id=&quot;newactivity&quot;&gt;NewActivity&lt;/h3&gt;

&lt;p&gt;“NewActivity” is an unread chat message or a missed call…or an unread +1 on your message…or you were invited to a group call with a unique combination of people and it spawned a new empty group in chat…&lt;/p&gt;

&lt;p&gt;It’s trash. It overwrites the “OnThePhone”/”Presenting” statuses (statusii? eh, eh?) we actually care about. I’ve also had calls where I read the message, but the log kept me on NewActivity until the call ended. For lulz.&lt;/p&gt;

&lt;p&gt;It’s trash; ignore it.&lt;/p&gt;

&lt;h2 id=&quot;red-the-light&quot;&gt;Red the Light&lt;/h2&gt;

&lt;h3 id=&quot;backstory--why-kasa&quot;&gt;Backstory / Why Kasa&lt;/h3&gt;

&lt;p&gt;Why the TP-Link &lt;a href=&quot;https://www.amazon.com/alexa-smart-light-bulb-wifi/dp/B08TB8QBB1&quot;&gt;Kasa KL125&lt;/a&gt;? A coworker with a #VerySmartHome had an extra to lend me for testing.&lt;/p&gt;

&lt;p&gt;This is my first smart bulb. For those like me that had never investigated, you can drop a smart bulb into a normal ceiling dome and connect to wifi. (You’ll have tougher luck if the light fixture is on a dimmer switch.)&lt;/p&gt;

&lt;p&gt;My requirements are RGB (color), wifi (not Bluetooth), and local API. It meets my needs* for $15.&lt;/p&gt;

&lt;p&gt;* - &lt;em&gt;v1.2 disclaimer:&lt;/em&gt; Kasa reluctantly meets your local API needs, and will not once they start shipping bulbs on v2.0 firmware.&lt;/p&gt;

&lt;p&gt;Once Kasa is very broken, the next places I would suggest looking are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.lifx.com/collections/lightbulbs/products/lifx-color&quot;&gt;LIFX&lt;/a&gt;. I spent all the time doing this 18 months into COVID-19 WFH. It’s finally time to defend dropping $35 on a lightbulb one time.&lt;/li&gt;
  &lt;li&gt;A &lt;a href=&quot;https://www.philips-hue.com/en-us/p/hue-bridge/046677458478&quot;&gt;Philips Hue Bridge&lt;/a&gt; to interact with once you reach enough bulbs to justify the cost. It aggregates your bulbs and provides a supported local API.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;kasa-code&quot;&gt;Kasa Code&lt;/h3&gt;

&lt;p&gt;This assumes you have installed Python (I’m on 3.10) and added it to your PATH during installation. You then need to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pip install python-kasa&lt;/code&gt; to use the &lt;a href=&quot;https://github.com/python-kasa/python-kasa&quot;&gt;python-kasa repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I tried solving this in PowerShell to avoid the dependency and failed. Kasa’s API is very undocumented, the &lt;a href=&quot;https://github.com/python-kasa/python-kasa&quot;&gt;python-kasa repo&lt;/a&gt; refers to the work done in Wireshark to figure all this out, and it’s not worth diving into deeper if Kasa hopes to break it again anyway.&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;nv&quot;&gt;$KasaBulbIP&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;&apos;192.168.12.34&apos;&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;$TeamsStatus&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-match&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;OnThePhone|Presenting&apos;&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;# call python externally to use python-kasa to change the light&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kasa&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;--bulb&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;--host&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$KasaBulbIP&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;hsv&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;70&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;100&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;Else&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;# set bulb back to normal&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kasa&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;--bulb&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;--host&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$KasaBulbIP&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;hsv&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;100&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;HSV – While you might equate smart home devices with the Herpes simplex virus, Hue/Saturation/Value is another way of notating the color you prefer. &lt;a href=&quot;https://colorpicker.me&quot;&gt;https://colorpicker.me&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;kasa-app&quot;&gt;Kasa App&lt;/h3&gt;

&lt;p&gt;The repo allows you to avoid the mboile app, but I used it to set up the light anyway. If you have a v1.2 bulb, skip the prompt to update upon connecting to it.&lt;/p&gt;

&lt;p&gt;It’s nice for the kids to play with changing colors, and I can still manually set red if I remember after hopping into Zoom instead of Teams.&lt;/p&gt;

&lt;h2 id=&quot;red-the-slack&quot;&gt;Red the Slack&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/images/teams-slack.png&quot; alt=&quot;teams-slack&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Before I had a bulb to try, I tried toggling status in my family Slack for my wife. This worked pretty well, it’s just not as effective as the bulb. Definitely keeping the work here in case it helps you.&lt;/p&gt;

&lt;h3 id=&quot;new-slack-app-and-key&quot;&gt;New Slack app and key&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://api.slack.com/authentication/basics&quot;&gt;https://api.slack.com/authentication/basics&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go to &lt;a href=&quot;https://api.slack.com/apps&quot;&gt;https://api.slack.com/apps&lt;/a&gt;, create a new app, then go to “OAuth &amp;amp; Permissions” and add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;users.profile:write&lt;/code&gt; to “User Token Scopes”. Then copy the User OAuth Token for use by your script.&lt;/p&gt;

&lt;p&gt;(You may also need &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;users.read&lt;/code&gt; once to &lt;a href=&quot;https://api.slack.com/methods/users.list&quot;&gt;grab the UserID&lt;/a&gt; you are modifying. That’s how I did it, anyway.)&lt;/p&gt;

&lt;h3 id=&quot;slack-code&quot;&gt;Slack Code&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;nv&quot;&gt;$SlackKey&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;&apos;xoxb-Numbers-Numbers-MoreNumbers-LongHexadecimal&apos;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$SlackUserID&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;&apos;U03QXXXXX&apos;&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;$TeamsStatus&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-match&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;OnThePhone|Presenting&apos;&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;$SlackStatus&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;c&quot;&gt;# slack status and message to set&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;status_text&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;&apos;Teams call&apos;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;status_emoji&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;&apos;:no_entry:&apos;&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;Else&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;$SlackStatus&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;c&quot;&gt;# slack status will be cleared&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;status_text&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;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;status_emoji&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;&apos;&apos;&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;c&quot;&gt;# Build Slack API call details&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Splat&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;nx&quot;&gt;Headers&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;nx&quot;&gt;Authorization&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;s2&quot;&gt;&quot;Bearer &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$SlackKey&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;s1&quot;&gt;&apos;Content-type&apos;&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;&apos;application/json&apos;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;charset&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;&apos;utf-8&apos;&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;nx&quot;&gt;Method&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;&apos;Post&apos;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Uri&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;&apos;https://slack.com/api/users.profile.set&apos;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Body&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;nx&quot;&gt;user&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;$SlackUserID&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;profile&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;$SlackStatus&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;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ConvertTo&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Json&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ErrorAction&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;&apos;Stop&apos;&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;$response&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;Invoke-RestMethod&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;Splat&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;task-scheduler&quot;&gt;Task Scheduler&lt;/h2&gt;

&lt;p&gt;100% of Old Windows Dads agree: Just set it as a dumb scheduled task and forget about it. If you don’t know how to run a PowerShell script in Task Scheduler, just Google this one.&lt;/p&gt;

&lt;p&gt;It should have a recurring trigger every minute.&lt;/p&gt;

&lt;p&gt;Most importantly, it should “Run whether user is logged on or not”, or you will see a very annoying window pop every minute. They are considering solving this in newer versions of PowerShell 7; see &lt;a href=&quot;https://github.com/PowerShell/PowerShell/issues/3028&quot;&gt;issue #3028&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This requires that you enter your password upon editing the task, and that your Windows user is a member of the “Log on as Batch Job” group. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lusrmgr.msc&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;in-conclusion&quot;&gt;In Conclusion&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/brianbunke/TeamsStatus&quot;&gt;https://github.com/brianbunke/TeamsStatus&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Like you care about more words here. I hope it helps!&lt;/p&gt;

</description>
        <pubDate>Sat, 06 Nov 2021 08:00:00 +0000</pubDate>
        <link>https://brianbunke.github.io/blog/2021/11/06/teams-hallway/</link>
        <guid isPermaLink="true">https://brianbunke.github.io/blog/2021/11/06/teams-hallway/</guid>
        
        <category>powershell</category>
        
        <category>api</category>
        
        <category>teams</category>
        
        <category>smarthome</category>
        
        
        <category>blog</category>
        
      </item>
    
      <item>
        <title>Do the Three</title>
        <description>&lt;p&gt;In the spirit of June, and because I’m thinking about this while posting another job opening, some career advice for recent graduates.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;If you want to be successful, people need to enjoy working with you.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That means:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Solve problems&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;If you skip this, you are (temporarily) being paid to not work.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Be curious&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;If you skip this, there is a ceiling on what you can solve (and what you get paid).&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Be friendly&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;If you skip this, it’s only a matter of time.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Make things better. Ask questions and investigate to help identify new problems, and then help solve those. Get along with people while you’re doing it.&lt;/p&gt;

&lt;p&gt;Can’t code? Do the three. Dyslexic, ADHD, etc.? Do the three. A good employer will mold work to amplify productive employees’ strengths, and look for others to complement skill sets and mitigate weaknesses.&lt;/p&gt;

&lt;p&gt;If you show up to work and do not see infinite problems to work on solving:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;You need to broaden your field of view. Ask a coworker about their problems.&lt;/li&gt;
  &lt;li&gt;You need to broaden your field of view…outside your current employer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some companies aren’t big enough, aren’t open-minded enough, or aren’t willing to compensate you for always getting things done in a friendly fashion. &lt;em&gt;Change&lt;/em&gt; your job, or &lt;em&gt;change your job.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Do the three, gravitate to others who do the three, and you will always have a path forward.&lt;/p&gt;
</description>
        <pubDate>Mon, 29 Jun 2020 08:00:00 +0000</pubDate>
        <link>https://brianbunke.github.io/blog/2020/06/29/do-the-three/</link>
        <guid isPermaLink="true">https://brianbunke.github.io/blog/2020/06/29/do-the-three/</guid>
        
        <category>advice</category>
        
        <category>manager</category>
        
        <category>itops</category>
        
        
        <category>blog</category>
        
      </item>
    
      <item>
        <title>New-InboxRule -MessageTypeMatches</title>
        <description>&lt;p&gt;A coworker asked for an Outlook rule that deleted all meeting responses. &lt;a href=&quot;https://www.extendoffice.com/documents/outlook/1894-outlook-remove-meeting-responses.html&quot;&gt;This walkthrough&lt;/a&gt; works if you’re sitting in front of Outlook, but there has to be a way to do it with Exchange Online PowerShell (EXOPS), 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;n&quot;&gt;New-InboxRule&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Mailbox&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;me@brianbunke.com&apos;&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;&apos;Delete meeting responses&apos;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-MessageTypeMatches&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;CalendaringResponse&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-DeleteMessage&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;span class=&quot;nt&quot;&gt;-StopProcessingRules&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;Just a quick writeup, because I was surprised I couldn’t find this while Googling. To figure it out, I had to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Get-Help New-InboxRule -Full&lt;/code&gt; and scan through… &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(Get-Help New-InboxRule -Full).parameters.parameter.Count&lt;/code&gt; …72 parameters to find roughly what I was looking for.&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;PS C:\&amp;gt; Get-Help New-InboxRule -Parameter MessageTypeMatches

-MessageTypeMatches &amp;lt;AutomaticReply | AutomaticForward | Encrypted | Calendaring | CalendaringResponse | PermissionControlled | Voicemail | Signed | ApprovalRequest | ReadReceipt | NonDeliveryReport&amp;gt;
[...]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This parameter does not implement a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[ValidateSet()]&lt;/code&gt; attribute, so the choices do not auto-populate. I had actually found this a few minutes prior and hoped &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl + Space&lt;/code&gt; (open the Intellisense menu) would solve my problem, to no avail.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One big gotcha:&lt;/strong&gt; Using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;New-InboxRule&lt;/code&gt;, whether on yourself or others, prevents the rule from being visible in the Outlook client. You must use Outlook Web Access (OWA) or EXOPS to see the rule you just created.&lt;/p&gt;

&lt;p&gt;Outlook client:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/outlook-rule-warning.png&quot;&gt;&lt;img src=&quot;/images/outlook-rule-warning.png&quot; alt=&quot;outlook-rule-warning&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;OWA ([https://outlook.office365.com]):&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EDIT Nov 2021:&lt;/strong&gt; I only delete “accepted” meeting responses now. Rejected responses are usually useful information, and often have a reason why in the body.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/owa-rule.png&quot;&gt;&lt;img src=&quot;/images/owa-rule.png&quot; alt=&quot;owa-rule&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Keep this in mind if you’re administratively populating rules, as it won’t be fun to learn after the fact. From my sleuthing, there is no fix for this today (June 2020).&lt;/p&gt;

</description>
        <pubDate>Mon, 22 Jun 2020 08:00:00 +0000</pubDate>
        <link>https://brianbunke.github.io/blog/2020/06/22/messagetypematches/</link>
        <guid isPermaLink="true">https://brianbunke.github.io/blog/2020/06/22/messagetypematches/</guid>
        
        <category>powershell</category>
        
        <category>exchange</category>
        
        <category>exops</category>
        
        
        <category>blog</category>
        
      </item>
    
      <item>
        <title>vCenter Simulator CI Pipeline</title>
        <description>&lt;p&gt;Have you ever wanted to test against VMware vCenter, but didn’t have a lab environment available? How about in an automated fashion, every time you commit new code?&lt;/p&gt;

&lt;p&gt;My &lt;a href=&quot;/blog/2018/12/31/vcenter-simulator-ci/&quot;&gt;prior post&lt;/a&gt; in this series introduces consuming the &lt;a href=&quot;https://github.com/vmware/govmomi/tree/master/vcsim&quot;&gt;govcsim&lt;/a&gt; project via Docker. With a containerized vCenter Simulator (&lt;a href=&quot;https://hub.docker.com/r/nimmis/vcsim&quot;&gt;VCSIM&lt;/a&gt;), not only can you locally test your VMware code without a lab environment, but you can get cute running automated tests as well.&lt;/p&gt;

&lt;p&gt;By storing your code in source control like GitHub, you are unlocking the potential of a continuous integration (CI) pipeline. After every new code commit, your CI pipeline can automatically start the VCSIM container, download &lt;a href=&quot;https://www.powershellgallery.com/packages/VMware.PowerCLI&quot;&gt;PowerCLI&lt;/a&gt;, and run your automated tests against the newest code you just committed.&lt;/p&gt;

&lt;p&gt;This walkthrough uses PowerCLI and &lt;a href=&quot;https://azure.microsoft.com/en-us/services/devops/pipelines/&quot;&gt;Azure Pipelines&lt;/a&gt;, but you could apply these concepts to any vSphere code (e.g. pyvmomi, govmomi) and any CI pipeline provider (e.g. GitLab, AppVeyor).&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 class=&quot;no_toc&quot; id=&quot;table-of-contents&quot;&gt;Table of Contents&lt;/h2&gt;

&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#github-vcsim-ci&quot; id=&quot;markdown-toc-github-vcsim-ci&quot;&gt;GitHub: vcsim-CI&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#azure-pipelinesyml&quot; id=&quot;markdown-toc-azure-pipelinesyml&quot;&gt;azure-pipelines.yml&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#buildps1&quot; id=&quot;markdown-toc-buildps1&quot;&gt;build.ps1&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#vcsimtestsps1&quot; id=&quot;markdown-toc-vcsimtestsps1&quot;&gt;!vcsim.Tests.ps1&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#viewing-results&quot; id=&quot;markdown-toc-viewing-results&quot;&gt;Viewing Results&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#current-hurdles&quot; id=&quot;markdown-toc-current-hurdles&quot;&gt;Current Hurdles&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;github-vcsim-ci&quot;&gt;GitHub: &lt;a href=&quot;https://github.com/brianbunke/vcsim-CI&quot;&gt;vcsim-CI&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;A GitHub repository can be connected to Azure DevOps as a new “project.” Every time you push a commit to the repo, Azure Pipelines can automatically trigger a new build to test the changes you just made: a CI pipeline.&lt;/p&gt;

&lt;p&gt;This repository uses three files in Azure Pipelines:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;azure-pipelines.yml&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;build.ps1&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Tests\!vcsim.Tests.ps1&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I tried to keep this as barebones as possible, to explain what I think is necessary and allow you to build from there. Let’s examine the contents of each file.&lt;/p&gt;

&lt;h3 id=&quot;azure-pipelinesyml&quot;&gt;azure-pipelines.yml&lt;/h3&gt;

&lt;p&gt;The presence of this file tells Azure Pipelines to run. What it does depends on the contents of the file.&lt;/p&gt;

&lt;p&gt;A .yml file means you’ll want to tab open a &lt;a href=&quot;https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema&quot;&gt;YAML schema reference&lt;/a&gt;, because that’s &lt;em&gt;#devops&lt;/em&gt; life in 2019.&lt;/p&gt;

&lt;p&gt;Allow me to quickly summarize what this file is doing:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Use a Microsoft-hosted Ubuntu VM
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vmImage: ubuntu-latest&lt;/code&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Download and run the &lt;a href=&quot;https://hub.docker.com/r/nimmis/vcsim&quot;&gt;VCSIM&lt;/a&gt; container locally on Ubuntu&lt;/li&gt;
  &lt;li&gt;Run the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;build.ps1&lt;/code&gt; PowerShell script (see next section)&lt;/li&gt;
  &lt;li&gt;Run your PowerShell/PowerCLI tests with the &lt;a href=&quot;https://github.com/pester/Pester&quot;&gt;Pester&lt;/a&gt; test framework&lt;/li&gt;
  &lt;li&gt;Read back the test results and store them in Azure Pipelines&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As of this writing, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ubuntu-latest&lt;/code&gt; = &lt;a href=&quot;https://github.com/Microsoft/azure-pipelines-image-generation/blob/master/images/linux/Ubuntu1604-README.md&quot;&gt;ubuntu-16.04&lt;/a&gt;. Note that Docker and PowerShell v6 are included in the image.&lt;/p&gt;

&lt;p&gt;Azure Pipelines can run Windows, Mac, and Linux jobs side-by-side, which enables you to provide excellent cross-platform support. However, the Windows Server images can’t run Linux-based containers, and the Mac images don’t include Docker. I’m running the container locally, so this leaves me with only Ubuntu of the Microsoft-hosted VMs to test on.&lt;/p&gt;

&lt;p&gt;I suspect these problems can be overcome, but I reached my patience threshold. Let me know if you have this working in Azure Pipelines on Windows or Mac!&lt;/p&gt;

&lt;h3 id=&quot;buildps1&quot;&gt;build.ps1&lt;/h3&gt;

&lt;p&gt;Really, all this file does is install PowerCLI (to connect to VCSIM from PowerShell) and Pester (to run PowerShell tests).&lt;/p&gt;

&lt;p&gt;For the sake of being thorough: it also trusts the PowerShell Gallery, runs first-time PowerCLI setup, and outputs the module versions in case you need to dig through the logs when troubleshooting.&lt;/p&gt;

&lt;h3 id=&quot;vcsimtestsps1&quot;&gt;!vcsim.Tests.ps1&lt;/h3&gt;

&lt;p&gt;Put all your Pester &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*.Tests.ps1&lt;/code&gt; files in the Tests directory. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Invoke-Pester&lt;/code&gt; runs test files alphabetically, so you’ll probably want the meta tests running first. The tests included in this first file:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Connectivity
    &lt;ol&gt;
      &lt;li&gt;Does it see VCSIM locally on port 443?&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;PowerCLI
    &lt;ol&gt;
      &lt;li&gt;Connect to VCSIM&lt;/li&gt;
      &lt;li&gt;Does it see the default number of datacenters, hosts, and VMs?&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You want a test expecting a non-zero number to be sure it’s connected. You don’t need three tests, but I kept them just as examples.&lt;/p&gt;

&lt;h2 id=&quot;viewing-results&quot;&gt;Viewing Results&lt;/h2&gt;

&lt;p&gt;In your GitHub repository, viewing your commit history will show ✅ or ❌ to denote whether any error was returned during each build. Clicking the “Details” link will take you to the Azure Pipelines build.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/vcsimci1.png&quot;&gt;&lt;img src=&quot;/images/vcsimci1.png&quot; alt=&quot;vcsimci1&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/vcsimci2.png&quot;&gt;&lt;img src=&quot;/images/vcsimci2.png&quot; alt=&quot;vcsimci2&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Whether these tests pass or fail, the test results will &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;always()&lt;/code&gt; publish back to Azure Pipelines.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/azurepipelinestests.png&quot;&gt;&lt;img src=&quot;/images/azurepipelinestests.png&quot; alt=&quot;azurepipelinestests&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;current-hurdles&quot;&gt;Current Hurdles&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://azure.microsoft.com/en-us/services/devops/pipelines/&quot;&gt;Azure Pipelines&lt;/a&gt; on the free plan doesn’t let you cache resources to speed up builds (e.g. container, modules).&lt;/p&gt;

&lt;p&gt;As alluded to above, I’m not sure if there is a better way to interact with VCSIM besides just running it locally. Most Pipelines documentation I found concerning Docker involves publishing containers, not consuming them.&lt;/p&gt;

&lt;p&gt;This is a good time to remind you that VCSIM mocks vSphere APIs, and is nowhere near full parity. (See &lt;a href=&quot;/blog/2018/12/31/vcenter-simulator-ci/&quot;&gt;prior post&lt;/a&gt; for how to generate the list of available methods.)&lt;/p&gt;

&lt;p&gt;It’s also difficult to define a static &lt;a href=&quot;https://github.com/vmware/govmomi/issues/1185&quot;&gt;simulator state&lt;/a&gt;. You can define the number of VMs generated, for example, but you can’t name or size them. (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker run --rm -d -p 443:443/tcp nimmis/vcsim --vm 0&lt;/code&gt;) In my testing with datastores specifically, datastore size jumped between three different values from test to test, and I had trouble adding my own via PowerCLI.&lt;/p&gt;

&lt;p&gt;If you can help teach me how to fix any of these problems upstream in the &lt;a href=&quot;https://github.com/vmware/govmomi/tree/master/vcsim&quot;&gt;govcsim&lt;/a&gt; source, I’ll definitely blog it. 😉&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;a href=&quot;https://github.com/brianbunke/vcsim-CI&quot;&gt;vcsim-CI&lt;/a&gt; on GitHub&lt;/p&gt;
&lt;/blockquote&gt;

</description>
        <pubDate>Tue, 24 Sep 2019 08:00:00 +0000</pubDate>
        <link>https://brianbunke.github.io/blog/2019/09/24/vcenter-simulator-ci-2/</link>
        <guid isPermaLink="true">https://brianbunke.github.io/blog/2019/09/24/vcenter-simulator-ci-2/</guid>
        
        <category>powershell</category>
        
        <category>powercli</category>
        
        <category>vmware</category>
        
        <category>vcsim</category>
        
        <category>docker</category>
        
        <category>pipeline</category>
        
        <category>pester</category>
        
        
        <category>blog</category>
        
      </item>
    
      <item>
        <title>REST Client in VS Code</title>
        <description>&lt;p&gt;Last year I &lt;a href=&quot;/blog/2018/05/02/proxy-to-fiddler&quot;&gt;blogged&lt;/a&gt; how to install &lt;a href=&quot;https://www.telerik.com/fiddler&quot;&gt;Fiddler&lt;/a&gt; and view raw HTTP request/response data when interacting with a remote REST API.&lt;/p&gt;

&lt;p&gt;Enter &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=humao.rest-client&quot;&gt;REST Client&lt;/a&gt;, a Visual Studio Code extension that solves this use case (and many more) in a much lighter fashion. After trying it out, I thought it was useful enough to deserve a quick write-up.&lt;/p&gt;

&lt;p&gt;Start to finish in four quick steps:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://code.visualstudio.com/&quot;&gt;VS Code&lt;/a&gt; &amp;gt; Extensions pane &amp;gt; Install &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=humao.rest-client&quot;&gt;REST Client&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Open a new file tab and set the language (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl + K, M&lt;/code&gt;) to HTTP&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;POST https://jsonplaceholder.typicode.com/posts&lt;/code&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://jsonplaceholder.typicode.com&quot;&gt;API reference&lt;/a&gt; for the test site&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;A “Send Request” link appears directly above that line; click it and the response tab appears to the right&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here’s a screenshot demonstrating how to send a body with your POST request:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/restclient1.png&quot;&gt;&lt;img src=&quot;/images/restclient1.png&quot; alt=&quot;restclient&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Really, the hardest part is digging through the massive readme to figure out how to do what you want amid all the other crazy features. There’s support for GraphQL, various authentication methods (Azure AD?!), proxies, cookies…it’s an impressive list. Go check it out!&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;em&gt;Credit to &lt;a href=&quot;https://twitter.com/tiberriver256/status/1172113350047797249&quot;&gt;@tiberriver256&lt;/a&gt; for sharing.&lt;/em&gt;&lt;/p&gt;

</description>
        <pubDate>Mon, 16 Sep 2019 08:00:00 +0000</pubDate>
        <link>https://brianbunke.github.io/blog/2019/09/16/rest-client-vs-code/</link>
        <guid isPermaLink="true">https://brianbunke.github.io/blog/2019/09/16/rest-client-vs-code/</guid>
        
        <category>vscode</category>
        
        <category>api</category>
        
        
        <category>blog</category>
        
      </item>
    
      <item>
        <title>VMware PowerCLI 101</title>
        <description>&lt;p&gt;&lt;a href=&quot;/images/HBI1743BU.jpg&quot;&gt;&lt;img src=&quot;/images/HBI1743BU.jpg&quot; alt=&quot;HBI1743BU&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At VMworld US 2019, &lt;a href=&quot;https://twitter.com/kmruddy&quot;&gt;Kyle Ruddy&lt;/a&gt; and I presented a session named “Introduction to PowerCLI.” In it, we demonstrated how to get started with &lt;a href=&quot;https://code.vmware.com/web/tool/vmware-powercli&quot;&gt;VMware PowerCLI&lt;/a&gt; to manage and automate your VMware environments. The goal was to make the command line a little more familiar – and a little less intimidating – especially if you have never used PowerCLI or &lt;a href=&quot;https://docs.microsoft.com/en-us/powershell/&quot;&gt;PowerShell&lt;/a&gt; before.&lt;/p&gt;

&lt;p&gt;About half the session was spent performing a live demo, because my hope is you can follow along back at your desk with the session recording and the exact code I used. The editor in the demo is &lt;a href=&quot;https://code.visualstudio.com/&quot;&gt;Visual Studio Code&lt;/a&gt;, allowing a consistent experience for any user. PowerShell, PowerCLI, and VS Code are all free and cross-platform.&lt;/p&gt;

&lt;p&gt;If you are interested in learning how to use PowerCLI in a walkthrough that gradually introduces core PowerShell patterns, consider grabbing the code and watching the video.&lt;/p&gt;

&lt;hr /&gt;

&lt;h4 id=&quot;hbi1743bu---introduction-to-powercli---session-recording&quot;&gt;HBI1743BU - Introduction to PowerCLI - session recording&lt;/h4&gt;

&lt;h3 id=&quot;stream--download&quot;&gt;&lt;a href=&quot;https://videos.vmworld.com/global/2019/videoplayer/27858&quot;&gt;Stream&lt;/a&gt; / &lt;a href=&quot;https://s3-us-west-1.amazonaws.com/vmworld-usa-2019/HBI1743BU.mp4&quot;&gt;Download&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Streaming requires a free VMworld account. All VMworld 2019 session downloads available via &lt;a href=&quot;https://github.com/lamw/vmworld2019-session-urls&quot;&gt;lamw’s repo&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h3 id=&quot;powercli101-on-github&quot;&gt;&lt;a href=&quot;https://github.com/brianbunke/PowerCLI101&quot;&gt;PowerCLI101 on GitHub&lt;/a&gt;&lt;/h3&gt;

&lt;hr /&gt;

&lt;p&gt;If you have any feedback on the material, please reach out via any of the icons below!&lt;/p&gt;

</description>
        <pubDate>Tue, 03 Sep 2019 08:00:00 +0000</pubDate>
        <link>https://brianbunke.github.io/blog/2019/09/03/powercli-101/</link>
        <guid isPermaLink="true">https://brianbunke.github.io/blog/2019/09/03/powercli-101/</guid>
        
        <category>powershell</category>
        
        <category>powercli</category>
        
        <category>vmware</category>
        
        <category>code</category>
        
        
        <category>blog</category>
        
      </item>
    
      <item>
        <title>Get-ShouldOperator</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;&lt;a href=&quot;https://github.com/pester/Pester/issues/878&quot;&gt;How do I discover Should operators?&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you’ve ever tried to learn &lt;a href=&quot;https://github.com/pester/Pester&quot;&gt;Pester&lt;/a&gt;, PowerShell’s foremost code testing framework, you probably recognize this question.&lt;/p&gt;

&lt;p&gt;Hopefully, you found the answers you needed on the &lt;a href=&quot;https://github.com/pester/Pester/wiki&quot;&gt;Pester wiki&lt;/a&gt;, but that’s not an ideal solution. The wiki is not updated with the same frequency as the project, and we want quick answers via our PowerShell console, not on the website.&lt;/p&gt;

&lt;p&gt;Enter &lt;a href=&quot;https://hacktoberfest.digitalocean.com&quot;&gt;Hacktoberfest&lt;/a&gt;. &lt;em&gt;(And associated nice swag.)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/hacktoberfest2018.jpg&quot;&gt;&lt;img src=&quot;/images/hacktoberfest2018.jpg&quot; alt=&quot;hacktoberfest2018&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After submitting some small PRs on other projects, I went hunting for a “&lt;a href=&quot;https://github.com/pester/Pester/labels/good%20first%20issue&quot;&gt;good first issue&lt;/a&gt;” on the Pester repository, and decided I was most interested in solving this problem.&lt;/p&gt;

&lt;p&gt;Soon, a &lt;a href=&quot;https://github.com/pester/Pester/pull/1116&quot;&gt;pull request&lt;/a&gt; was born. After some discussion and tweaks, and subsequent testing and acceptance by &lt;em&gt;(super deserving Microsoft MVP)&lt;/em&gt; &lt;a href=&quot;https://twitter.com/nohwnd&quot;&gt;Jakub&lt;/a&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Get-ShouldOperator&lt;/code&gt; makes its debut in Pester’s brand new &lt;a href=&quot;https://github.com/pester/Pester/releases/tag/4.5.0&quot;&gt;4.5.0&lt;/a&gt; release.&lt;/p&gt;

&lt;p&gt;The use case is simple: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Get-ShouldOperator&lt;/code&gt; returns every assertion operator available to Pester. By default, the displayed operators ship with Pester, but you would also see any custom registrations you may have added with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Add-AssertionOperator&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/getshouldoperator1.png&quot;&gt;&lt;img src=&quot;/images/getshouldoperator1.png&quot; alt=&quot;getshouldoperator1&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s say “Contain” sounds like what you’re looking for. You can quickly get a synopsis of what it does, and view the example(s) pulled from the Pester wiki:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/getshouldoperator2.png&quot;&gt;&lt;img src=&quot;/images/getshouldoperator2.png&quot; alt=&quot;getshouldoperator2&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;4.5.0 is available on the &lt;a href=&quot;https://www.powershellgallery.com/packages/Pester&quot;&gt;PowerShell Gallery&lt;/a&gt;. Run your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Install-Module Pester&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Update-Module Pester&lt;/code&gt; commands today, and start using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Get-ShouldOperator&lt;/code&gt; to help you get quicker answers!&lt;/p&gt;

</description>
        <pubDate>Fri, 11 Jan 2019 08:00:00 +0000</pubDate>
        <link>https://brianbunke.github.io/blog/2019/01/11/get-shouldoperator/</link>
        <guid isPermaLink="true">https://brianbunke.github.io/blog/2019/01/11/get-shouldoperator/</guid>
        
        <category>powershell</category>
        
        <category>pester</category>
        
        <category>hacktoberfest</category>
        
        
        <category>blog</category>
        
      </item>
    
      <item>
        <title>vCenter Simulator Docker Container</title>
        <description>&lt;p&gt;One of the primary issues with developing tools focused on VMware is the lack of a readily available vCenter lab to test against. At times, I have had a functional and up-to-date &lt;a href=&quot;https://twitter.com/brianbunke/status/619970996708093952&quot;&gt;home lab&lt;/a&gt;, and right now it sits in neglectful disrepair. When you develop open-source tooling, this problem is uniquely inflicted upon every potential contributor.&lt;/p&gt;

&lt;p&gt;The original incarnation of vCenter Simulator (VCSIM) was a useful tool to help bridge this gap, but it last emulated vCenter 5.5.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/vmware/govmomi/tree/master/vcsim&quot;&gt;govcsim&lt;/a&gt; is a new version of VCSIM, written in the Go language (Golang), intended to mock the API endpoints presented by vCenter Server and ESXi. While it is written in Golang, once it’s running, any language capable of interacting with an API can consume it. &lt;em&gt;(*cough* PowerShell)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In addition, it can be packaged as a Docker container, which makes end-user consumption even easier. This walkthrough uses &lt;a href=&quot;https://hub.docker.com/r/nimmis/vcsim&quot;&gt;nimmis/vcsim&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;PowerCLI can connect to a VCSIM Docker container and run commands against it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I am using Docker Desktop on Windows 10 Enterprise. (&lt;a href=&quot;https://docs.docker.com/docker-for-windows/install/&quot;&gt;Install Docker for Windows&lt;/a&gt;) Docker must be running in Linux mode, as VCSIM is a Linux-based container.&lt;/p&gt;

&lt;p&gt;That said: Docker, PowerShell v6+ (pwsh), and PowerCLI v10+ are all cross-platform, so you can run and interact with VCSIM from pretty much whereever you want. (Consider this a teaser for my next blog post.)&lt;/p&gt;

&lt;p&gt;This code will:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Run a new VCSIM container.
    &lt;ul&gt;
      &lt;li&gt;If you don’t have the image locally, it will download from Docker Hub.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;On Windows, get the local IP address of your DockerNAT network adapter.
    &lt;ul&gt;
      &lt;li&gt;tl;dr - On Win10, Hyper-V + Docker + NAT doesn’t work the way you’d expect.&lt;/li&gt;
      &lt;li&gt;You will be connecting to a local IP address like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;10.0.75.1&lt;/code&gt;, &lt;em&gt;not&lt;/em&gt; localhost.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;After starting the container, test that port 443 is responding.
    &lt;ul&gt;
      &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-TCPPort&lt;/code&gt; parameter was introduced in PowerShell v6.&lt;/li&gt;
      &lt;li&gt;If you’re using Windows PowerShell and still want to test port connectivity, &lt;a href=&quot;https://stackoverflow.com/questions/9566052/how-to-check-network-port-access-and-display-useful-message&quot;&gt;see Stack OverFlow&lt;/a&gt;.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Use the &lt;a href=&quot;https://www.powershellgallery.com/packages/VMware.PowerCLI&quot;&gt;VMware.PowerCLI&lt;/a&gt; PowerShell module to connect to vCenter Simulator and test drive it.&lt;/li&gt;
&lt;/ol&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;docker&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;--rm&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;443:443/tcp&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;nimmis/vcsim:latest&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;bp&quot;&gt;$IsMacOS&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-or&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;$IsLinux&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;$Server&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;&apos;localhost&apos;&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;Else&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;$Server&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;n&quot;&gt;Get-NetIPAddress&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-InterfaceAlias&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;docker&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;nt&quot;&gt;-AddressFamily&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;IPv4&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;IPAddress&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;bp&quot;&gt;$PSVersionTable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;PSVersion&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Major&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-ge&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;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;Test-Connection&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Server&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-TCPPort&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;443&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;Connect-VIServer&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Server&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Server&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Port&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;443&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-User&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Password&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# Did it work?&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Get-VM&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# Or Get-VMHost, or Get-Datastore, etc.&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 simulator currently supports a subset of API methods. Once the container is running, you can view the list of supported methods and types:&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;nv&quot;&gt;$About&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;Invoke-RestMethod&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Uri&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;https://&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Server&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;:443/about&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Method&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Get&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$About&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Methods&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$About&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Types&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;For example, some of the methods include &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PowerOffVM_Task&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PowerOnMultiVM_Task&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PowerOnVM_Task&lt;/code&gt;. From PowerCLI, try out your trusty &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Stop-VM&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Start-VM&lt;/code&gt; commands &lt;em&gt;(after you’ve disconnected from your production environment)&lt;/em&gt;!&lt;/p&gt;

&lt;p&gt;If you’d like VCSIM to do something it currently doesn’t support, open an issue on the open-source &lt;a href=&quot;https://github.com/vmware/govmomi&quot;&gt;govmomi&lt;/a&gt; library.&lt;/p&gt;

&lt;p&gt;Coming up: My next post will detail how you can incorporate this Docker image into an &lt;a href=&quot;https://azure.microsoft.com/en-us/services/devops/pipelines/&quot;&gt;Azure DevOps build pipeline&lt;/a&gt;, providing an avenue to run integration tests with your code in a CI pipeline without connecting to an existing vSphere environment.&lt;/p&gt;

</description>
        <pubDate>Mon, 31 Dec 2018 08:00:00 +0000</pubDate>
        <link>https://brianbunke.github.io/blog/2018/12/31/vcenter-simulator-ci/</link>
        <guid isPermaLink="true">https://brianbunke.github.io/blog/2018/12/31/vcenter-simulator-ci/</guid>
        
        <category>powershell</category>
        
        <category>powercli</category>
        
        <category>vmware</category>
        
        <category>vcsim</category>
        
        <category>docker</category>
        
        
        <category>blog</category>
        
      </item>
    
      <item>
        <title>Get-PSConferenceBook</title>
        <description>&lt;p&gt;I’m proud, grateful, and excited to report that my chapter on Azure Functions in &lt;a href=&quot;https://leanpub.com/powershell-conference-book&quot;&gt;The PowerShell Conference Book&lt;/a&gt; has just been published!&lt;/p&gt;

&lt;p&gt;We made this book for one reason: We needed a PowerShell version of &lt;em&gt;The Simpsons&lt;/em&gt; classic &lt;a href=&quot;http://simpsons.wikia.com/wiki/22_Short_Films_About_Springfield&quot;&gt;22 Short Films About Springfield&lt;/a&gt; episode.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/psconfbook1.jpg&quot;&gt;&lt;img src=&quot;/images/psconfbook1.jpg&quot; alt=&quot;Gum in Lisa&apos;s Hair&quot; /&gt;&lt;/a&gt;
&lt;em&gt;You are Lisa, and we’re all just trying to help.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Ok, maybe that wasn’t the only reason. &lt;a href=&quot;https://twitter.com/mikefrobbins&quot;&gt;Mike Robbins&lt;/a&gt; wrote more about &lt;a href=&quot;https://mikefrobbins.com/2018/07/06/announcing-the-powershell-conference-book/&quot;&gt;the project’s genesis&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this book, you’ll get unique chapters from over 30 authors, each speaking about areas of specific interest. In that way, it’s like a conference…there is an overarching theme (PowerShell), and many stories of the different paths the technology allows you to explore.&lt;/p&gt;

&lt;p&gt;Not only will you find many different perspectives behind one cover, but your money is also supporting a great cause. From the book’s Leanpub page:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;All (100%) of the royalties from this book are donated to the OnRamp scholarship program. More information about &lt;a href=&quot;https://powershell.org/summit/summit-onramp/&quot;&gt;the OnRamp track&lt;/a&gt; at the PowerShell + DevOps Global Summit and &lt;a href=&quot;https://powershell.org/summit/summit-onramp/onramp-scholarship/&quot;&gt;their scholarship program&lt;/a&gt; can be found on the &lt;a href=&quot;https://powershell.org/&quot;&gt;PowerShell.org website&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You know what I wish I had when I was first getting into IT? Money to attend a conference, in order to learn the trade and connect with its practicioners. I’m happy the book’s proceeds will help bridge that gap for a couple people who may not otherwise have the opportunity.&lt;/p&gt;

&lt;p&gt;Throw some more really cool PowerShell stuff onto your toolbelt while supporting a great cause. Consider picking up a copy!&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://leanpub.com/powershell-conference-book&quot;&gt;&lt;img src=&quot;/images/psconfbook2.jpg&quot; alt=&quot;The PowerShell Conference Book cover&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;https://leanpub.com/powershell-conference-book&quot;&gt;The PowerShell Conference Book&lt;/a&gt;&lt;/p&gt;

</description>
        <pubDate>Thu, 19 Jul 2018 14:00:00 +0000</pubDate>
        <link>https://brianbunke.github.io/blog/2018/07/19/powershell-conference-book/</link>
        <guid isPermaLink="true">https://brianbunke.github.io/blog/2018/07/19/powershell-conference-book/</guid>
        
        <category>powershell</category>
        
        <category>conference</category>
        
        <category>book</category>
        
        <category>azure</category>
        
        <category>functions</category>
        
        <category>simpsons</category>
        
        
        <category>blog</category>
        
      </item>
    
  </channel>
</rss>
