PowerShell Function: Set-WindowsTheme

I am a heavy Mac user these days, but still carry a Windows laptop with me in my bag for support of my clients and some light gaming. I love that my Mac sets the theme between light and dark mode. So I set out to find a way to do this.

Sadly, there I could not find a way to do this on sunrise and sunset, however I was able to find a way to do this at a PowerShell prompt. So introducing Set-WindowsTheme. You can add this function to your PowerShell profile, and then set the theme between light and dark mode at will.

Insider Threat Podcast: Episode 1

I am proud to announce that Insider Threat: The #misec Podcast episode 1 has been released.

Insider Threat: The #misec podcast is a bi weekly podcast highlighting the security community in the state of Michigan while providing insight and access to trends and industry professionals across security disciplines.

Episode 1: It Has To Start Somewhere is available here as well as the following podcast services:

  • Apple
  • Spotify
  • Stitcher
  • Tune In

Please follow the podcast on twitter at @insiderthreatpod.

I will be keynoting BSides Detroit 2019

I am extermely honored to announce that I will be keynoting BSides Detroit 2019 on November 15th at TechTown Detroit. This will be my first keynote and am proud to give it at the conference that I helped run for years and hold near to my heart.

The title of my talk is Communal Benefits – How to hack your career while making friends.

Here is the abstrct:
Just like most people, I owe a ton of where I am in my career to the infosec community. From BSides Detroit to #misec to PoshSec and everywhere in between, I would not be where I am today. One side effect of the community that has literally saved my life is the close friends I have made by sticking my neck out and participating. By the end of this talk, I will give you 5 was to hack your career, gain friends, and rule the world.

You can find out more about the event and grab a ticket on the Security BSides website.

I hope to see you there!

Creating Updatable Help for your PowerShell Module

For a long time I have wanted to do updatable help for the PoshSec PowerShell module. For some reason, I was never able to put two and two together to actually get updatable help implemented. This is my guide as to how I did it in preparation for the upcoming PoshSec 2.0 release.

What is updatable help?

Updatable help is a feature of PowerShell that lets you download updates to the help files associated with PowerShell. To update help on your own computer, you would run Update-Help at a PowerShell prompt that is running as administrator. This will then go fetch the newest version of help files from the internet.

How do we implement updatable help?

There are a few prerequisites to be able to use updatable help with your PowerShell module.

  1. A place to host your help files. I will be hosting PoshSec’s on the PoshSec web server.
  2. The platyPS module. This module is published by the Microsoft PowerShell team and allows you to create PowerShell help files using Markdown. You can grab the module by downloading it at https://github.com/PowerShell/platyPS or by running Install-Module -name platyPS at an elevated PowerShell prompt.
  3. A module you can load using Import-Module.
  4. Comment based help for your functions and commands.

Next you need to be in the directory you would want to store the help files. I am storing mine in the root of my Github directory in a folder named docs. See the picture below of my PoshSec folder structure on my desktop.

And inside of my docs folder I have three folders. They are named Cab, en-US and Markdown respectively.

These directories are important along each step of the updatable help journey. Lets begin by importing our module. Obviously, you would import the module you are doing the help for.

Import-Module -Name PoshSec

Once the module is imported, you are going to generate the Markdown help files. This is where the first directory comes into place. From my Github root directory, I run the following command:

New-MarkdownHelp -Module PoshSec -WithModulePage -OutputFolder .\Docs\Markdown

The module parameter and the output folder parameters are pretty self explanatory, but the -WithModulePage needs a little discussion. This Markdown file contains a list of descriptions of the commands or functions found within the module. This is the beggining of my PoshSec.md file created with the above command. I had to edit the descriptions of each command in the file.

Here is a look into what the PoshSec.md file is before I edited the file. The lines that the red arrows are the lines I edited. The first arrow is the link where you are going to store the help files. The PoshSec module help files are stored at https://www.poshsec.com/help/. Second, you edit the module help version number. Since PoshSec is working towards version 2.0, I filled in You would update this with the version number you need for your project. The last two arrows are examples of things that I needed to edit to get this to work.

Here is a look at the completed PoshSec.md file that I have created for my updatable help files.

Once you are done editing, you are ready to move on to the next step.

The next step after editing the Markdown files, you are going to create the MAML (also known as Microsoft Assistance Markup Language) files. MAML files are what Updatable help uses to update the help files on your computer. You can edit MAML files directly, but using platyPS is much easier. The command below is what I used to create the MAML file for PoshSec. Again, I am running this command from the root directory of the PoshSec Module.

New-ExternalHelp .\Docs\Markdown -OutputPath .\Docs\en-US\

This command is pretty straight forward. If you are generating help in other languages, you can modify the output path to have that language qualifier. Like I said, this command is really simple and straight forward.

Now onto the final step. This last step before copying to your hosting provider is to create the actual CAB file that the Update-Help command actually downloads and installs. This command puts all the pieces together. The first parameter, -CabFilesFolder is the location of the CAB files you created in the last part. The -LandingPagePath parameter is the Markdown file you created above and edited with your module information. Finally, the -OutputFolder parameter is where you want to drop your CAB file.

New-ExternalHelpCab -CabFilesFolder .\Docs\en-US\ -LandingPagePath .\Docs\PoshSec.md -OutputFolder .\Docs\Cab\

Here is a view of my CAB folder. It is a little misleading as all three files are created, but no worries. You now have your files that you need for updatable help.

Next you are going to update your .PSD1 file to have the help file location. You are going to open your module file and search for the HelpInfoURI section. It should be commented out or you are going to have to create the line. This is what PoshSec’s looks like after I edited it.

Now it is time to copy your help files to a location you can use with Update-Help. Once you are done, you are going to want to re-import your module and then run Update-Help. Here are the commands that I used in order to validate my new help files worked.

Remove-Module -Name PoshSec
Import-Module -Name PoshSec
Update-Help -Module -Verbose -Force

Note: You can only run Update-Help once a day without the -Force Parameter.

This is what it looks like when I run Update-Help -Module PoshSec -Verbose -Force


Hopefully, with this post you have discovered that publishing updatable help is really easy with platyPS. This method has worked for me for PoshSec and hopefully it can help you with your module as well.

If you have any questions, please reach out to me on Twitter or email and Happy Scripting!

Quick Hit – Copy-VSCodeUserSnippets

It should be no surprise that I am a VS Code user. VS Code is an amazing editor and it’s free. One of the things I love about it is the ability to make something called a user snippet.

According to the VS Code website, a user snippet is a template that make it easier to enter repeating code patterns, such as loops or conditional-statements. I use user snippets for PowerShell related items, but also text files, Python and Go snippets as well.

So since I like to send everything “code” related to a Git repository, I figured I would write a PowerShell function to copy my user snippets to another directory that I have in a Git repo.

So in all it’s glory. Here it is.