BadBlood Update Feb 5 2021

If you are unaware of what Badblood is, it’s an Active Directory domain generator that sets up a domain for training, testing, or whatever. It makes a mess in a domain.

Only use it in testing

I haven’t put much thought into the tool since it’s release, and that is quite the disservice to the community. People seem to like the idea of the tool. (As of today when I wrote this post it had 603 stars on GitHub) It works, and it’s easy to set up.

If I had to write a mission statement for development for BadBlood, it would be something like, “Enable every human the ability to create a test domain.”

Guiding principles for development would be:

  1. Make it easy
  2. Make it quick
  3. Make it useful

I was working on another side project, (totally unrelated to anything I’ve ever done before and not even security related) and out of curiosity I clicked on my old friend, BadBlood. I saw a pull request on the master repo. It was from a very unknown person and it was a very basic idea: a domain size selector.

I thought, “Why the hell not?” And I got curious. Saw the code made sense, read through it, decided it was a good idea, and clicked pull.

Now friends, never pull without testing the code first

I went to sleep without any hesitation, thinking “Would you look at that! BadBlood isn’t dead!”

I woke up at around 3 am with a stark realization. What the heck did I pull without testing for!? and nearly kicked myself down to my office to fix my no testing, pull blunder my 3am self realized I had made.

Luckily for me, I have no issues emptying my mind and falling back asleep. I figured not many people would pull and test a new update to a repo at 3am EST.


An unknown-to-me developer named HuskyHacks added a piece to the invoke-badblood script. It was a gui based array selector that modified the size of the domain deployed by BadBlood. The update was gui based added more steps to the person running BadBlood. Because it added more steps to the tool, I didn’t believe that it went in line with the idea of “Make it easy” or “make it quick.” I moved the idea into parameters inside the tool.


   [Parameter(Mandatory = $false,
      Position = 1,
      HelpMessage = 'Supply a count for user creation default 2500')]
   [Int32]$UserCount = 2500,
   [Parameter(Mandatory = $false,
      Position = 2,
      HelpMessage = 'Supply a count for user creation default 500')]
   [int32]$GroupCount = 500,
   [Parameter(Mandatory = $false,
      Position = 3,
      HelpMessage = 'Supply the script directory for where this script is stored')]
   [int32]$ComputerCount = 100

badblood update user group computer count

I set the defaults on the tool to use a set number of objects

ObjectDefault size

badblood update user group computer count

Now you can easily set the default number of users, groups, and computers that you want to deploy by specifying these variables.

Stuff to skip laps and OU creation

After testing these new parameters I fixed a minor annoyance. I ran, re-ran, and re-re-ran BadBlood a few times in a temp domain and got really annoyed with the LAPS and OU creation portions erroring out because they already ran. I decided to add a couple of switch parameters to allow the user of BadBlood to skip the OU and Laps setup.

  [Parameter(Mandatory = $false,
      Position = 4,
      HelpMessage = 'Skip the OU creation if you already have done it')]
   [Parameter(Mandatory = $false,
      Position = 5,
      HelpMessage = 'Skip the LAPS deployment if you already have done it')]

By adding these parameters into the script you can now reload even more randomness into a domain any time you want.

badblood update user group computer count


if ($PSBoundParameters.ContainsKey('SkipLapsInstall') -eq $false)
         Write-Progress -Activity "Random Stuff into A domain" -Status "Progress:" -PercentComplete ($i / $totalscripts * 100)
         .($basescriptPath + '\AD_LAPS_Install\InstallLAPSSchema.ps1')
         Write-Progress -Activity "Random Stuff into A domain: Install LAPS" -Status "Progress:" -PercentComplete ($i / $totalscripts * 100)

OU Skip

 if ($PSBoundParameters.ContainsKey('SkipOuCreation') -eq $false)
         .($basescriptPath + '\AD_OU_CreateStructure\CreateOUStructure.ps1')
         Write-Progress -Activity "Random Stuff into A domain - Creating OUs" -Status "Progress:" -PercentComplete ($i / $totalscripts * 100)

Other edits

Other than that there were some minor formatting items that I remedied. Having not opened the tool and the code for about a year, I found it hard to read some of the code in the invoke function.

I’ll try to find some more time to keep adding to BadBlood in the future. Hope you enjoy it, and connect with me via Twitter or LinkedIn and let me know what you think about what needs to be added next!