September 15th, 2018

Using PowerShell to create a folder of Demo data

Doctor Scripto
Scripter

Summary: Creating sample files with random sizes and dates for use in a Lab

Q: Hey, Dr. Scripto!

From time to time I like to show “how things works” at User Group meetings and to colleagues.   But I don’t always have a good pile of sample files.   Do you have any examples of how to create some “Demo data”?

—SH

A: Hello SH,

I actually ran into the same problem a few weeks ago when I was writing an article.   I needed exactly that!

What I needed was a folder full of sample files with not only random file names, but random content and even random dates.

Just *how* could I achieve that?

The first thought I had was “Just generate random filenames of numbers and put in a generic bit of content.”

This simple solution would be a start

# Provide Folder name and create $Folder=’C:\Demo’

New-Item -ItemType Directory -Path $Folder

# Create a series of 10 files for ($x=0;$x -lt 10; $x++)

{ # Let’s create a completely random filename $filename=”$($Folder)\$((Get-Random 100000).tostring()).txt”

# Now we’ll create the file with some content Add-Content -Value ‘Just a simple demo file’ -Path $filename

}

There! A repeatable solution to create 10 simple files!

Oh but wait, they were two problems I saw. Both were irritating.

  • Each file was the same size
  • Each filename was just a number followed by txt

These things I could improve.   I decided with preclude the number with a name like ‘LogFile’ so at least they *could* look a bit more legitimate.

For content…. How could I solve that?

I decided on a second loop of random limits and to populate it with ASCII values.

The useful values in ASCII (vs. PetSCII or ATASCII if you’re REALLY a Nerd from the ‘80’s) numbered from 32 to 96.   Those values would give me everything from a blank space to a little “Backtick”

Get-Random would work but it would start from 0 to a number. I needed to ensure I picked a numeric range between 32 and 96.

This was solved using this statement

(Get-Random 64)+32

Now the only challenge was to convert the Number to a Character.   You can convert an ASCII character to it’s numeric equivalent using the following statement. (Here we convert the letter ‘A’ to it’s ASCII equivalent).

We can REVERSE the process by swapping them around and providing the numeric equivalent.

To get my Random Number as character (Provide I have a range of values between 0 and 255 as a result) I would use this statement.

[char][byte]((Get-Random 64)+32)

So create a random string of content I just created a simple loop such as this.

# We’re going to build files up to 1K in size

   $limit=(Get-random 1024)

     # Let’s build the random content    for($y=0;$y -lt $limit;$y++)    {

       # We’re building a content of pure ASCII data        $a=$a+[char][byte]((Get-Random 64)+32)

   }

Ok… it didn’t produce deep reading material, but I could produce random content up to 1 kilobyte in size to replace for the little string that read ‘Just a simple demo file’

To alter the filename to have “Logfile” at the beginning I simply injected the name into the string like this.

$filename=”$($Folder)\Logfile$((Get-Random 100000).tostring()).txt”

If you’re new to PowerShell I could also have put the pieces of the string together individually like this.

$filename=$Folder+’\Logfile’+((Get-Random 100000).tostring())+’.txt’

Let’s review

  • Each file now has a unique size and content
  • Each filename now has something a little more to the name

I was sitting there pleased with myself. I could easily alter the value and have Thousands of files.

“Muah ha ha ha haaaa!” I cackled like Doctor Frankenstein who is about to give life to the monster!

….and then (don’t you those?)

I realized every single file was just a sequence of the same date and time.   I wanted to be able to have content that had random dates and times.

For this I had to go up a level in permissions with using Administrative rights (Remember this is for DEMO content)

I knew with PowerShell I can access and CHANGE the current date and time with the following two Cmdlets.

Get-Date

Set-Date

I also knew I could adjust the Date and Time in precise increments in the following fashion

$TimeDifference=New-TimeSpan -Minutes 30

Set-Date -Adjust $TimeDifference

Now the wheels were churning.   I needed a loop to do the following

  • Pick a random number of days, hours and minutes (and remember them!)
  • Create a Timespan
  • Adjust the Set-Date with said Timespan
  • Once time was adjusted, create my file (Which would be stamped with this random date)
  • Create a “Negative Timespan” to undo my playing with the Clock
  • Correct the Date.

Now I’m certain many of you have access to a T.A.R.D.I.S. but good old Dr. Scripto doesn’t, so here at the Scripting Blog we use PowerShell.

Here’s an example of that very code that adjusts the time, creates the file and then Sets time back. Or mostly back at least.

   $DaysToMove=((Get-Random 120) -60)    $HoursToMove=((Get-Random 48) -24)    $MinutesToMove=((Get-Random 120) -60)    $TimeSpan=New-TimeSpan -Days $DaysToMove -Hours $HoursToMove -Minutes $MinutesToMove

   # Now we adjust the Date and Time by the new TimeSpan    # Needs Admin rights to do this as well!

     Set-Date -Adjust $Timespan | Out-Null

   # Create that file    Add-Content -Value $a -Path $filename

   # Now we REVERSE the Timespan by the exact same amount    $TimeSpan=New-TimeSpan -Days (-$DaysToMove) -Hours (-$HoursToMove) -Minutes (-$MinutesToMove)

   Set-Date -Adjust ($Timespan) | Out-Null

Now pleased with the results…. The Script was re-run

There are other things I could do to this script, such as have it test for existence of the Demo folder or ensure filenames were never duplicated.   But this was to create some basic “dummy Data”.

If you have to create a demo environment, you can use similar techniques to these for populating Active Directory users or SQL tables as well.

I hope this was a fun and informative read for you today and that you’re enjoying the weather as well!

I invite you to follow the Scripting Guys on Twitter and Facebook. If you have any questions, send email to them at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow.

Until we meet again, just remember we can all change the one world with just one Cmdlet at a time!

Cheers!

Sean Kearney, Premier Field Engineer, Hey Scripting Guy

Windows PowerShell, Sean Kearney, Hey Scripting Guy

Author

The "Scripting Guys" is a historical title passed from scripter to scripter. The current revision has morphed into our good friend Doctor Scripto who has been with us since the very beginning.

2 comments

Discussion is closed. Login to edit/delete existing comments.

  • ludovic Solczynski

    Hi,
    If you only random file name and random file size, you can do it faster with the fsutil command line.
    Sample :
    Param(    [Parameter(Mandatory=$false, HelpMessage="Specify the directory to use.")]    [string] $directory,    [Parameter(Mandatory=$false, HelpMessage="Specify the number of files to create.")]    [int] $fileNumber,    [Parameter(Mandatory=$false, HelpMessage="Specify the min file size. (In bytes)")]    [int] $minSize,    [Parameter(Mandatory=$false, HelpMessage="Specify the max file size. (In bytes)")]    [int] $maxSize,    [Parameter(Mandatory=$false, HelpMessage="Specify the max...

    Read more
  • Frode Flaten

    Good tip!
    There's no need to change the system time. The time-properties in FileInfo are writeable. Ex.
    PS> $t = Get-Item test.txt; $t | Get-Member -Name *time
       TypeName: System.IO.FileInfo
    Name           MemberType Definition----           ---------- ----------CreationTime   Property   datetime CreationTime {get;set;}LastAccessTime Property   datetime LastAccessTime {get;set;}LastWriteTime  Property   datetime LastWriteTime {get;set;}
    PS > dir test* | fl *time
    CreationTime   : 21.02.2019 09:56:47LastAccessTime : 21.02.2019 09:56:47LastWriteTime  : 21.02.2019 09:56:47
    PS > $create = [datetime]"1/1/2000"PS > $t.CreationTime = $createPS > dir...

    Read more