Pester – Validate home directory share permissions

In our company a user’s home directory is created through a script. Unfortunately, the script had been somewhat broken for at least a few months. Home directories created during that time have wrong permissions and need to be fixed.

With hundreds of home directories this needs to be scripted – so I thought why not use Pester for that.

Describing Tests ACL of [\\homedrive\home$\jsp\]
   Context jsp
    [+] ACL should contain only 3 ACEs 66ms
    [+] ACL should contain [mydomain\fileradmins] 14ms
    [+] ACL should contain [mydomain\Domain-Admins] 13ms
    [+] ACL should contain [mydomain\jsp] 14ms
Describing Tests ACL of [\\homedrive\home$\jsp\MyScans]
   Context jsp
    [+] [\\homedrive\home$\jsp\MyScans] should exist 83ms
    [+] ACL should contain only 4 ACEs 9ms
    [+] ACL should contain [mydomain\printerserviceaccount] 15ms
Tests completed in 219ms
Passed: 7 Failed: 0 Skipped: 0 Pending: 0

Describing Tests ACL of [\\homedrive\home$\pfisterer\]
   Context pfisterer
    [-] ACL should contain only 3 ACEs 65ms
      Expected: {3}
      But was:  {4}
      at line: 10 in \\homedrive\home$\megamorf\gitlab\HomedrivePermissions\HomedrivePermissions.Tests.ps1
      10:             $Acl.Access.Count | Should Be 3
    [-] ACL should contain [mydomain\fileradmins] 14ms
      Expected: {FullControl}
      But was:  {}
      at line: 18 in \\homedrive\home$\megamorf\gitlab\HomedrivePermissions\HomedrivePermissions.Tests.ps1
      18:             $ACE.FileSystemRights  | Should Be 'FullControl'
    [-] ACL should contain [mydomain\Domain-Admins] 13ms
      Expected: {FullControl}
      But was:  {}
      at line: 30 in \\homedrive\home$\megamorf\gitlab\HomedrivePermissions\HomedrivePermissions.Tests.ps1
      30:             $ACE.FileSystemRights  | Should Be 'FullControl'
    [-] ACL should contain [mydomain\pfisterer] 14ms
      Expected: {Modify, Synchronize}
      But was:  {}
      at line: 42 in \\homedrive\home$\megamorf\gitlab\HomedrivePermissions\HomedrivePermissions.Tests.ps1
      42:             $ACE.FileSystemRights  | Should Be 'Modify, Synchronize'
Describing Tests ACL of [\\homedrive\home$\pfisterer\MyScans]
   Context pfisterer
    [+] [\\homedrive\home$\pfisterer\MyScans] should exist 110ms
    [-] ACL should contain only 4 ACEs 10ms
      Expected: {4}
      But was:  {5}
      at line: 66 in \\homedrive\home$\megamorf\gitlab\HomedrivePermissions\HomedrivePermissions.Tests.ps1
      66:             $Acl.Access.Count | Should Be 4
    [+] ACL should contain [mydomain\printerserviceaccount] 16ms
Tests completed in 244ms
Passed: 2 Failed: 5 Skipped: 0 Pending: 0

By default our home directories have Access Control Entries (ACEs) for the domain admins and storage admins groups with full access and the respective user account with modify permissions. For our printers’ “scan to home directory”-feature we have to ensure that a folder called MyScans exists in the user’s home directory. That folder needs an additional ACE of the printing service account with write permissions.


Pester – Server deployment tests

Hey guys, here’s one of the basic tests I use to check if I’ve forgotten anything after deploying a server:


As you can see the test accepts a Computername parameter. I’m using a wrapper function to run the test against a selection of computers like this:



Quick Tip: Set-ADAccountPassword -Whatif fixed with Server 2016

Hey guys,

just a quick heads-up to all of those who had to deal with this unfortunate bug:

Set-ADAccountPassword -Identity $User -NewPassword $Password -Whatif

Sets the password anyway. I checked by looking at the passwordlastset attribute of the user and found it had been reset.

It’s going to be fixed with Server 2016 according to Microsoft:

This is fixed in Windows Server 2016 and the accompanying RSAT.



WMF5 is to re-release at end of February

Updated 02/08/2016 – Thank you for your continued patience. We have fixed the offending PSModulePath issue and tested it thoroughly. We are working towards getting properly signed WMF 5.0 RTM builds. Now, we expect that around end of February you will be able to download the revised packages.


Gitlab in Production – Part 2: Design Goals

Welcome to part 2 of my Gitlab in Production series where I’ll guide you through the process of getting Gitlab set up yourself.

These are my design goals:


  • run Gitlab CE on-premise
  • server-side OS is Linux
  • client-side OS is Windows
  • create basic operating manual for my team (git & gitlab)
  • hardening (even though the server is not going to be exposed to the internet it should be secured appropriately)
  • using gitlab should be as easy and accessible as possible (we have a number of mouse jockeys on our team, go figure :/ )
  • document Gitlab upgrade procedure
  • create required documentation (network diagram, recovery scenarios, etc.)


  • create concept for Gitlab CI (Continuous Integration) which is included since version 8
  • use Gitlab CI to run test and build tasks for our projects

As you can see these requirements are not out of the ordinary. Implementation should be a breeze but as always you’ll see that things can be more complicated than you thought.

Stay tuned for part 3 where I cover the Linux setup and basic hardening steps.

Gitlab in Production – Part 1: Introduction

Most of you are probably somewhat familiar with github or have at least heard of the source control system git. But what is Gitlab exactly? Wikipedia describes Gitlab as follows:

GitLab, the software, is a web-based Git repository manager with wiki and issue tracking features.

And indeed, that is Gitlab in a nutshell. You can either host your projects on the official and publicly hosted Gitlab servers or run your own instance in the cloud/on-premise.

Gitlab dashboard

Gitlab itself comes in two flavours: as free Community Edition (CE) or paid Enterprise Edition (EE). The main difference between these two, as the name implies, is that Gitlab EE is under a proprietary license, and contains features not present in the CE version.

The Gitlab software is based on ruby and supports the following operating systems (as of 2016.02.15):

  • Ubuntu 12.04
  • Ubuntu 14.04 (recommended, for 15.04 select and download the package manually)
  • Debian 7
  • Debian 8
  • CentOS 6 (and RedHat/Oracle/Scientific Linux 6)
  • CentOS 7 (and RedHat/Oracle/Scientific Linux 7)
  • Raspberry PI 2 on Raspbian Wheezy

In the course of this blog series I’m going to cover hosting your own Gitlab CE instance with the necessary hardening measures required for production use.

Stay tuned for part 2.


Pester – Operational validation

I’ve started using Pester for practical validation scenarios in our company. I recently discovered that someone from our SQL consulting company has disabled the firewall on all of our Windows Server 2012 R2 machines that run SQL Server 2014 – a thing that I’m not going to tolerate.

Here’s the firewall test code. You’ll see that I’m using a Pester feature called Testcases in order to minimize redundant code. Unfortunately, test cases are not described in the Pester wiki on github – I believe they’d be more widely used if that were the case.

PS ov:\> ls

    Directory: D:\Pester
Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       14.02.2016     13:30           2000 FirewallStatus.Tests.ps1

PS ov:\> Invoke-Pester

Describing Firewall is enabled
 [+] tests if the Domain Profile is enabled 3.02s
 [+] tests if the Public Profile is enabled 199ms
 [+] tests if the Private Profile is enabled 211ms

Tests completed in 3.43s
Passed: 3 Failed: 0 Skipped: 0 Pending: 0 Inconclusive: 0
PS ov:\> Invoke-Pester -Script @{ Path = '.'; Parameters = @{ ComputerName = 'localhost' } }

Describing Firewall is enabled 

 [+] tests if the Domain Profile is enabled 2.95s
 [+] tests if the Public Profile is enabled 168ms
 [+] tests if the Private Profile is enabled 218ms

Tests completed in 3.34s
Passed: 3 Failed: 0 Skipped: 0 Pending: 0 Inconclusive: 0


Stay tuned for my post-deployment validation tests.