Tag Archives: New-TimeSpan

Proving PowerShell’s Usefulness to Newbies, Part II

Back again with another example to share with the Windows PowerShell newbies. They’re out there: people that don’t know the practical power in PowerShell. The idea is to use real-world examples of things we simply wouldn’t want to do manually, in hopes that our lost friends will find the light. Maybe, that’s you.

Part I can be found here. In that post, we learned that we could use PowerShell to create 10,000 folders in about 10 seconds — that’s 1,000 folders per second, or 1 folder each millisecond.

Part II
What we’ll do today is read in the content of a file, sort the items we’ve read in, and then write our sorted results back out to the same file — it’s instant alphabetizing. Let’s start by reading in our file and see what we’re starting with.

PS> Get-Content -Path .\file.txt
web02.mydomain.com
web09.mydomain.com
dc03.mydomain.com
dc04.mydomain.com
sql08.mydomain.com
sql06.mydomain.com
dc08.mydomain.com
sql04.mydomain.com
dc10.mydomain.com
web01.mydomain.com
web03.mydomain.com
dc09.mydomain.com
web05.mydomain.com
web06.mydomain.com
dc02.mydomain.com
web07.mydomain.com
dc05.mydomain.com
web04.mydomain.com
web10.mydomain.com
sql01.mydomain.com
dc01.mydomain.com
sql03.mydomain.com
sql10.mydomain.com
web08.mydomain.com
sql05.mydomain.com
sql07.mydomain.com
dc07.mydomain.com
sql02.mydomain.com
sql09.mydomain.com
dc06.mydomain.com

Our file contains 30 fully-qualified servers names that are in no significant order. Sorting all 30 of these server names is probably going to be difficult, or at least, it’s going to be time consuming. Wrong. With one quick addition to the previous command — see the example below — our list is sorted and without any noticeable difference in the amount of time it took to complete.

PS> Get-Content -Path .\file.txt | Sort-Object
dc01.mydomain.com
dc02.mydomain.com
dc03.mydomain.com
dc04.mydomain.com
dc05.mydomain.com
dc06.mydomain.com
dc07.mydomain.com
dc08.mydomain.com
dc09.mydomain.com
dc10.mydomain.com
sql01.mydomain.com
sql02.mydomain.com
sql03.mydomain.com
sql04.mydomain.com
sql05.mydomain.com
sql06.mydomain.com
sql07.mydomain.com
sql08.mydomain.com
sql09.mydomain.com
sql10.mydomain.com
web01.mydomain.com
web02.mydomain.com
web03.mydomain.com
web04.mydomain.com
web05.mydomain.com
web06.mydomain.com
web07.mydomain.com
web08.mydomain.com
web09.mydomain.com
web10.mydomain.com

Yeah, that was tough. I ran this same command 10 times, measuring it with the Measure-Command cmdlet, so I could see the average amount of time it took to sort the list of computers. It completed this “challenge” in anywhere between 6 and 10 milliseconds. I’m sorry, but it would’ve taken me at least a few minutes do to this by hand.

Now that we know we can sort it, let’s write it back to disk. In this example, below, we’ll put our sorted results back into the file where it came from, overwriting the original contents. If you don’t want to do that, then be sure to alter the file name value for Set-Content’s -Path parameter.

PS> Get-Content -Path .\file.txt | Sort-Object | Set-Content -Path .\file.txt
PS>

Let’s verify that our file now contains the sorted contents by rerunning our first Get-Content command from the beginning of this post.

PS> Get-Content -Path .\file.txt
dc01.mydomain.com
dc02.mydomain.com
dc03.mydomain.com
dc04.mydomain.com
dc05.mydomain.com
dc06.mydomain.com
dc07.mydomain.com
dc08.mydomain.com
dc09.mydomain.com
dc10.mydomain.com
sql01.mydomain.com
sql02.mydomain.com
sql03.mydomain.com
sql04.mydomain.com
sql05.mydomain.com
sql06.mydomain.com
sql07.mydomain.com
sql08.mydomain.com
sql09.mydomain.com
sql10.mydomain.com
web01.mydomain.com
web02.mydomain.com
web03.mydomain.com
web04.mydomain.com
web05.mydomain.com
web06.mydomain.com
web07.mydomain.com
web08.mydomain.com
web09.mydomain.com
web10.mydomain.com

That’s it. We ran a one-liner command to read in some data, sort it, and push it right back to the same file. So we were able to compare, I went ahead and sorted the same, 30-line file manually. It took me 3 minutes and 30 seconds (proof below). While this wasn’t the most complex, or lengthy document one might sort, the time difference is still quite drastic. PowerShell has plenty to offer, and spending some time to learn it is going to pay off. This line of work requires all the time you have to continue to learn, and stay relevant. PowerShell can give you some time back.

PS C:\> $StartTime = Get-Date
PS C:\> $EndTime = Get-Date
PS C:\> New-TimeSpan -Start $StartTime -End $EndTime


Days              : 0
Hours             : 0
Minutes           : 3
Seconds           : 30
Milliseconds      : 860
Ticks             : 2108600828
TotalDays         : 0.00244051021759259
TotalHours        : 0.0585722452222222
TotalMinutes      : 3.51433471333333
TotalSeconds      : 210.8600828
TotalMilliseconds : 210860.0828

Extra – PowerShell Summit North America 2015 [#1]

Read them all here: http://tommymaynard.com/extra-powershell-summit-north-america-2015-0-2015/

I decided I am going to write about my experience at my first PowerShell Summit—from beginning to end. The word ‘beginning’ is being used a bit loosely, as the PowerShell North America 2015 Summit is still 55 days away (see how I figured that out below). Regardless, I continue to find myself looking forward to this opportunity as it has every potential to be the highlight of my IT career, and so I’m going to post about it.

PS C:\> (New-TimeSpan -Start (Get-Date) -End 4/20/2015).Days
55
PS C:\> "$((New-TimeSpan -Start (Get-Date) -End 4/20/2015).Days) Days"
55 Days

Although, I’ve been registered for the summit for a few months now, and had my plane tickets for nearly as long, I just secured my hotel room. There was a bit of an internal debate with myself about where to stay. While some mentioned they prefer downtown, I just couldn’t expect that the daily cab fare both ways, and perhaps the extra cost of a downtown hotel, would be worth it. I really don’t know the first thing about North Carolina, or Charlotte, so it’s quite possible that I am very, very wrong.

That said, if anyone reading this is staying near the venue and wants to venture downtown for a meal, perhaps with others, then feel free speak up. Spitting the cab fare up a time or two would definitely be worth it, especially to discuss PowerShell over dinner. That is just something I cannot do with my wife and children. At least not often, and not for long—trust me, I’ve tried.

I’d be willing to discuss PowerShell over a meal closer to the venue, too. I’ve never eaten at a Ruby Tuesday, but that’s the closest food to my hotel. I added the link for me, but feel free to look at all the incredible food coming my way. Honestly, until today, I thought Ruby Tuesday was a buffet for retirees and grandparents, but some of that food looks surprisingly appetizing. The place looks much more appealing than I had assumed, too.

Moving on. Long before I knew I’d be attending the summit, PowerShell.org mentioned a program called Verified Effective. While the cost to take the test had always been mildly prohibitive, I was ecstatic to discover that the cost of the summit included this opportunity. Well, up until the program was cancelled really close after the time when I registered. My emotions were really being played with, even more so when I found out it was back on, although I was excited again. The difference was that the test would have to be taken in person (not remotely), and at the summit. I seriously may have been the first person to click and register on the Eventbrite URL that came via email. Based on opening the exam up to approximately 60 people, it appears that as of today, a touch more than half of the Verified Effective registrations have been claimed. I’m nervous, but looking forward to this opportunity.

I recently decided to read Don Jones’ and Jeffery Hicks’ Month of Lunches PowerShell books (book one & book two). I’ve finished the first one and a little over half way to complete the second title. I’d like to get these signed by their authors, but simply couldn’t do that without reading the books first. While I already know most of what I’ve read thus far, it has been a beneficial and comprehensive review. I long worried that in my learning, which was never front to back in any PowerShell book, that I may have missed something here and there. I had, and I’ve been filling in those little holes nicely since January. I would, without question, recommended these two titles to anyone that wants to learn PowerShell. They would’ve been a great way to learn, had I started with them first. Just find the money, buy them, learn it, and thank the three of us later—more so to them, of course.

I’ll stop here for now, but will be back with more summit ramblings as I find time and topics to cover. This really is going to be an amazing event. I’ll be up close and personal to people that think like I do, and that love automation and PowerShell. This occasion is going to bring together all the rock stars and celebrities of the PowerShell community. If you don’t hear more from me before my flight in April, then you can at least expect I’ll be writing on April 19th from the sky, somewhere between Arizona and North Carolina.

Find Time between Two Dates

This post will show two ways to determine the time span between two datetimes.

Earlier this year we performed a data migration to our data center. One of the Assistant Directors sent me an instant message first thing on a Monday morning to ask if the migration was complete. I had read that it completed earlier that morning and so I replied with the time at which it ended. The second question was how long the entire data migration took. I knew it started at 11 a.m. on Friday and that it completed at 7:21 a.m. on Monday. I could have done this in my head (11 a.m. Friday to 11 a.m. Monday equals 3 days, minus 4 hours, etc.) but I trust Windows PowerShell with dates, times, and time spans more than I do myself.

The first thing I did was assign a variable, $StateDate, with the date and time when the data migration started. After testing to see it held the proper date and time, I created a second variable, $EndDate, and assigned it the date and time when the data migration ended. I also checked that it stored the correct date and time before moving on.

PS C:\> $StartDate = Get-Date '5/9/2014 11:00:00 AM'
PS C:\> $StartDate

Friday, May 09, 2014 11:00:00 AM

PS C:\> $EndDate = Get-Date '5/12/2014 07:21:00 AM'
PS C:\> $EndDate

Monday, May 12, 2014 7:21:00 AM

I was aware of the New-TimeSpan cmdlet, which we’ll use below, but I wondered if I could simply subtract the start date (the smaller date and time) from the end date (the larger date and time). I tried and it worked! Two days, 20 hours, 21 minutes.

PS C:\> $EndDate - $StartDate

Days              : 2
Hours             : 20
Minutes           : 21
Seconds           : 0
Milliseconds      : 0
Ticks             : 2460600000000
TotalDays         : 2.84791666666667
TotalHours        : 68.35
TotalMinutes      : 4101
TotalSeconds      : 246060
TotalMilliseconds : 246060000

Here’s an example of using the New-TimeSpan cmdlet. Using this cmdlet may be easier, as to not confuse which date to subtract from which.

PS C:\> New-TimeSpan -Start $StartDate -End $EndDate

Days              : 2
Hours             : 20
Minutes           : 21
Seconds           : 0
Milliseconds      : 0
Ticks             : 2460600000000
TotalDays         : 2.84791666666667
TotalHours        : 68.35
TotalMinutes      : 4101
TotalSeconds      : 246060
TotalMilliseconds : 246060000

I didn’t want anything more returned to me other than the days, hours, and minutes. I piped my results from the New-TimeSpan cmdlet to the Select-Object cmdlet and specified the properties I wanted returned. The output wasn’t great (see the final example on this page) and so I took those results and piped them to the Format-List cmdlet.

PS C:\> New-TimeSpan -Start $StartDate -End $EndDate | Select-Object Days,Hours,Minutes | Format-List

Days    : 2
Hours   : 20
Minutes : 21

Here’s how I finished up. I created a new variable, $TimeSpan, and assigned it the results of the New-TimeSpan cmdlet piped the Select-Object cmdlet. Before going any further, I tested that the variable’s value was storing what I wanted. Once I was sure the  variable contained what I wanted, I modified it a bit and sent it to the clipboard so it could be easily pasted into my instant messenger program.

PS C:\> $TimeSpan = New-TimeSpan -Start $StartDate -End $EndDate | Select-Object Days,Hours,Minutes
PS C:\> $TimeSpan

                                   Days                                   Hours                                 Minutes
                                   ----                                   -----                                 -------
                                      2                                      20                                      21

PS C:\>"$($TimeSpan.Days) Days, $($TimeSpan.Hours) Hours, $($TimeSpan.Minutes) Minutes" | clip