Formating dates with Powershell for different purposes

So Windows has lots of date formats to choose from. These are a few and functions to convert between them and Datetime.


The default timeformat that we are using in .NET and Powershell. This is probably the first date function you will learn to use. Or you can call on the .NET class.


Microsoft built time format that calculates number of 100 ns intervals since January 1, 1601. Yes this is a really large number. But even though the name suggest this is always for files it isn’t. Also in some file systems the resolution isn’t 100 ns just because the format has that as the smallest incrment.

I did a blog entry about a small discrepancy depending when creating dates using different methods and how they differed by 100ns. This was most easy to spot while looking at the time in a FileTime format.

MSDN page for FileTime structure

DMTF (Distributed Management Task Force) DateTime

As used by AD for some attributes and WMI. The format is almost easy to read.


Unix Epoch

This is the standard format used by *nix based systems. Number of seconds since January 1, 1970.

Also if you dont care about being compatible to older version you could use the [DateTimeOffset] class.

What about the other way then? That is really simpler.

From Event to Object

So I needed to do gather some information on the usage on a Fileserver so we enabled auditing but those logs aren’t that fun. Using the event viewer isn’t really an option with thousands of logentries to process. So I went to Powershell which has Get-WinEvent which returns [System.Diagnostics.Eventing.Reader.EventRecord] objects. But those still isnt that fun, they are event logs so I cant just do a Where-Object search on them as the message is a textblock. BUT I can convert them into XML which allows me to do queries on the XML with Where-Object but that still is limiting as I needed to do convertions, and depending on Powershell version you can do it different ways. So I did a cmdlet to do those for me so I dont have to in the future.

It reads the events you throw at it and create a translation map from the XML to a Powershell object.

So I created ConvertFrom-VirotEvent, a small sample below.

Sample ConvertFrom-VirotEvent
Lets see all times somebody used runas, eleveted them selfs using UAC or RDP.. Well anytime windows presented a loginbox for an already logged on user. Or other process did this to as the taskscheduler.

Or we can just group the SourceUserName




You can download the script from the Microsoft Technet Galleries.


Every function has a beginning, a middle and an end.

Okey so I used a bit of artistic freedom there, the truth is that the main parts of a function is:

  • Parameters
  • Begin
  • Process
  • End


So this is kinda self-explanatory. This is where we input all our parameters that the function will use. For today this is not really an important part so for simplicity I have created an input parameter called….(drumroll).. Input.


This script-block contains things that isn’t really dependent on any parameters that you supply. Here would be a good spot to verify that you have any required modules, have write access or connect to a database.


This is the big script-block that has all the magic. All your core logic goes in here.


When you are done there might be things cleanup or close. Close any database connection that you opened in the beginning.

So whats up with text and no powershell?? Okey here we go.

How it works with code
[Read more…]

Reverting the AdminSDHolders changes

So everyone knows what the AdminSDHolders does. Okey lets do a short version of that too.

The AdminSDHolder is what is that then.

Well windows has a few “protected” groups and users. If you are a member of one of these protected groups, Windows will do a few things every 60 minutes by default.

  • Set the AdminCount property of a user to 1
  • Disable inheritance on the user object
  • Set the rights on the user objects to a reduced set

This is an extremely simplified version. For more information please read in the Technet article AdminSDHolder.

Users and groups that by default are managed by the AdminSDHolder

Name Type
Administrator User
Account Operators Group
Administrators Group
Backup Operators Group
Cert Publishers Group
Domain Admins Group
Domain Controllers Group
Enterprise Admins Group
Krbtgt User
Print Operators Group
Read-only Domain Controllers Group
Replicator User
Schema Admins Group
Server Operators Group
[Read more…]

Remember who you are in a powershell window

So sometimes you run the same command so many times that you want it run at every time you start a powershell windows.

There are several profiles that can be loaded depending on how powershell is started. And there are also global policies for all users of a computer.


AllHosts are run for all types of Powershell, both regular console and ISE sessions. CurrentHost runs just for that specific so you can have different settings for ISE and console sessions.

The basic structure for the profiles are:

  • Locations:
    • Current user:  “$([environment]::getfolderpath(“mydocuments”))\WindowsPowerShell”
    • All users: “$($env:systemroot)\System32\WindowsPowerShell\v1.0\”
  • Filenames:
    • All types: profile.ps1
    • Console: PowerShell_profile.ps1
    • ISE:  PowerShellISE_profile.ps1

Since I am usually have more than one powershell at a time running with alternative credentials I had a hard time remember which windows was which. Of course I could have just run “whoami”, but that is also more work than needed. So I decided that placing the Username in the title was the way to go. This is also a good place to place other functions that you have written and you call all the time.

powershell with domain-username  [Read more…]

Cleaning out NetBIOS Hostnames from your DFSs

So you have been using DFS for a while and is happy. But you still get some complaints. Smaller companies usually hear that employees have problems accessing the DFS from home on their own computers. In larger companies it is usually not allowed to use private computers anyway. But there we have the problem with partner or purchased companies having problems with the DFS. So what is up?

The common problem is that you still are using hostnames instead of FQDN. So what does that matter really? It works great on my workstation. Most commonly companies automatically tries with the domain that the computer is joined into. This works great for the employees computers but not others. So what is happening then? Suppose we have a company called Contoso with a domain called contoso.local (I know its bad to have a .local domain name). You request the DFS called \\contoso.local\dfs, you will then contact the domain controllers in contoso.local domain and get which file servers are working as the root servers. If the response only contains netbios names the clients will try to attach the domain suffix from DNS (Unless configured differently using GPOs).

So I was at a customers doing a brief DFS analysis. So these are the scripts I ran to check the domainbased DFS. So these are some screenshots from a non-production environment:




[Read more…]

An extra 100ns for free?

So I was reading up on the AD Module filters. I found a thing, Microsoft usually says keep it simple. I found an over complex way of initializing a date variable. So what did the documentation suggest:

Whoa.. Yes you can use .NET but if possible use Powershell cmdlets. Do we have any cmdlet we can use? Get-Date. Get-Date can be initialized with year, month and day.

That looks easier to read so it is better. But are they the same. And they arent. So what is the difference? Let’s convert it to the FileTime structure.

Here we see that we get a 100-nanosecond difference. Im not really sure why. But now we know that if you want the real 12am you cant use Get-Date. As it will add a 100ns extra. Bonus link to MSDN article for DateTime Structure.

Updating AD group membership if the user has a mobilenumber


So I was at a customers location and well we got talking about scripts. They had the need for a script that populates a group if the user has a cellphone number configured and remove him the number is removed after.
They had already a script that did it. The script did what was needed but I felt there was room for improvement, so I got rid of a try catch where the catch was empty. That is just as bad as ON ERROR RESUME NEXT from the old VBScript days. Anyway I thought later there has got to be a better way of doing this.

The old way:

This is a compressed version written from memory.

The improved way:

So why not just be happy. Well there is still performance improvements and let the DC do the heavy lifting. Lets start using LDAPFilter.

But I only want user from one part of my AD

Okay so now we got new requirements of course but that is really simple. Lets just instruct the Get-ADUser to search only in one part using SearchBase.

So just add the searchbase parameter and path.

GUID Endian Converter

What is a GUID

First lets check what Microsoft says about the GUID:

“GUIDs are the Microsoft implementation of the distributed computing environment (DCE) universally unique identifier (UUID)”

Well what is a UUID then? Lets check RFC4122:

This specification defines a Uniform Resource Name namespace for
UUIDs (Universally Unique IDentifier), also known as GUIDs (Globally
Unique IDentifier). A UUID is 128 bits long, and can guarantee
uniqueness across space and time. UUIDs were originally used in the
Apollo Network Computing System and later in the Open Software
Foundation’s (OSF) Distributed Computing Environment (DCE), and then
in Microsoft Windows platforms.

So now we know that the GUID is a value which should be unique (there is not such thing as a guaranteed unique since there is no central authority). So lets check how the GUID is built and why this entry is needed.

Structure of a GUID

Lets look at a sample GUID ED7BA470-8E54-465E-825C-99712043E01C. Here there is a small difference between the UUID and the GUID specification, but it does not change anything. Both start using one 32bit Unsigned Integer followed by two 16bit Unsigned Integers. Then the UUID is specified as two 8bit Unsigned Integers followed by 6 bytes. Where as the GUID is specified as 8 bytes. But it does nothing to change the problem or the solution so lets leave it as 8 bytes.

The problem

RFC4122 specifies that the GUID must be precented as big endian but Intel processors are little endian. This is where the problem comes from. There are some applications that read the GUID in little endian format and store it as a string which does not do the little to big endian conversion by magic. In these cases you need to use a cmdlet as mine to convert between the endian formats. [Read more…]

Get the SID of all domains in a forest

I got a request from a system owner what was the SID of the domain since their license was bound to the domain SID. The Domain SID is not really that is going to change and its really unlikely that anyone will collide with yours, so not really a bad choice.

Anyways if you have the Active Directory Powershell module its really easy to do this. Without the AD Powershell module its not really that hard either, but Im lazy when the three latest published versions of Windows has the modules available I feel that I can skip doing it the long way.

Lets continue with the show:

And there we go, easy as 1-2-3