Quantcast
Channel: Scripting Blog
Viewing all 2129 articles
Browse latest View live

Weekend Scripter: Use PowerShell to Document Scheduled Tasks

$
0
0

Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to document scheduled tasks.

Microsoft Scripting Guy, Ed Wilson, is here. One of the really cool things about Windows PowerShell is the way that it builds on itself. When I learn a little bit about Windows PowerShell, I can apply those principles to accomplish other things. It does not matter what I am working with, Windows PowerShell works the same. Today, I have a great example.

I have seen several comments, and even received a few emails to scripter@microsoft.com asking about documenting scheduled tasks. People generally want to know the action that a task is supposed to do, and what the last results of that task were. If they can get the output in a CSV file so they can open it in Microsoft Excel, so much the better.

I thought this would be a cool way to end Scheduled Tasks Week. So here is a script—not too complicated—that does the following:

  1. Obtains a list of all scheduled tasks, beginning with a specific folder, and performs a recursive lookup for scheduled tasks in that folder and all subfolders.
  2. Creates a custom Windows PowerShell object that contains the name, status, results, next run time, execution command, and arguments for that command.
  3. Exports the custom object to a CSV file for further analysis.

To accomplish these objectives, I'll use the following Windows PowerShell cmdlets and functions:

  • Get-ScheduledTask
  • Foreach-Object
  • Get-ScheduledTaskInfo
  • Export-CSV

In addition to these functions and cmdlets, I'll use a hash table to create a custom Windows PowerShell object by using the [PSCustomObject] type accelerator. I also use a subexpression to obtain the last run value and the next run value from embedded objects.

The first thing I do is create two variables and assign string values to them. The $taskPath variable holds the path to scheduled tasks folders. $taskPath notation requires a backslash ( \ ) at the beginning and end of the string. I use an asterisk ( * ) as a wildcard character to search through all of the folders. Here is the command:

$taskPath = "\microsoft\*\"

$outcsv = "c:\fso\taskdef.csv"

The scheduled task folder structure is shown here:

Image of menu

Now I use the Get-ScheduledTask function to retrieve all of the scheduled task objects from the folders. I pipe the scheduled task objects to the Foreach-Object cmdlet so that I can create a custom object from each task as it comes across the pipeline. Here is that section of the script:

Get-ScheduledTask -TaskPath $taskPath |

    ForEach-Object { [pscustomobject]@{

The [pscustomobject] type accelerator accepts a hash table. Therefore, I begin and close the hash table as shown here:

@{}

In between the braces, I use a value for my property name, and I set it equal to an expression on the other side. The first one is easy—I get the task name and path:

Name = $_.TaskName

Path = $_.TaskPath

The next two things I want are the last result and the next time it will run. These come from the results of the Get-ScheduledTaskInfo function. I use a subexpression to cause the code to execute, and to bring back the results so I can assign it to my property values. Here is that code:

LastResult = $(($_ | Get-ScheduledTaskInfo).LastTaskResult)

NextRun = $(($_ | Get-ScheduledTaskInfo).NextRunTime)

As shown here, I pick up the state of the scheduled task. Is it ready to run, running, disabled, or “what have ya”?:

Status = $_.State

The command that will execute and arguments to that command are from objects embedded in the Actionsproperty of my scheduled task object. I can use dotted notation to retrieve those values:

Command = $_.Actions.execute

Arguments = $_.Actions.Arguments

I pipe the output to the Export-CSV cmdlet and create the CSV file. I use the –NoTypeInformation parameter to prevent the creation of a type header in the CSV file. Here is that command:

Export-Csv -Path $outcsv -NoTypeInformation

The complete script is shown here:

$taskPath = "\microsoft\*\"

$outcsv = "c:\fso\taskdef.csv"

Get-ScheduledTask -TaskPath $taskPath |

    ForEach-Object { [pscustomobject]@{

     Name = $_.TaskName

     Path = $_.TaskPath

     LastResult = $(($_ | Get-ScheduledTaskInfo).LastTaskResult)

     NextRun = $(($_ | Get-ScheduledTaskInfo).NextRunTime)

     Status = $_.State

     Command = $_.Actions.execute

     Arguments = $_.Actions.Arguments }} |

        Export-Csv -Path $outcsv -NoTypeInformation

Here is the CSV file when I open it in Microsoft Excel:

Image of spreadsheet

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

Ed Wilson, Microsoft Scripting Guy 


PowerTip: Create XML Representation of Scheduled Task

$
0
0

Summary: Learn how to export a scheduled task to XML by using Windows PowerShell.

Hey, Scripting Guy! Question How can I use Windows PowerShell to create an XML representation of a scheduled task?

Hey, Scripting Guy! Answer Use the Get-ScheduledTask function and pipe the results to the Export-ScheduledTask function,
           for example:

Get-ScheduledTask applog | Export-ScheduledTask

Weekend Scripter: Use PowerShell to Remotely Create Scheduled Task and Folder

$
0
0

Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to remotely create a scheduled task and folder.

Microsoft Scripting Guy, Ed Wilson, is here. On Friday in Use PowerShell to Create Scheduled Task in New Folder, I created a pretty long Windows PowerShell script that creates a folder for scheduled tasks, and creates, enables, and configures a scheduled task.

Over the weekend, I received several emails to scripter@microsoft.com that said basically, “That is all good, but I need to create the same scheduled task on a hundred servers. I cannot run around to run this script on all of them.”

Dude (or dudette), this is actually pretty easy because since Windows PowerShell 2.0, Windows PowerShell has had remoting built in. In fact, the server version of the operating system has Windows PowerShell remoting enabled by default.

I do not even need to write a script to run a script. I can do this in one line. Here is that line of code (I could make the command a bit shorter by using aliases and a positional parameter, but it would be even harder to read than it is now):

Invoke-Command -ComputerName (Get-ADComputer -filter * -SearchBase 'ou=servers,dc=nwtraders,dc=com').name -FilePath C:\fso\CreateScheduledTaskFolderAndTask.ps1

So what I decided to do was to write a short script that would do this configuration for me...

The first thing I do is create my search base string. This specifies the organizational unit that I will query. Because I only want these scheduled tasks to be on servers (not on domain controllers or workstations), I query an organizational unit called servers. Here is my search base:

$searchBase = "ou=servers,dc=nwtraders,dc=com"

Next I need to specify the path to the script. The cool thing is the script does not need to exist on the remote servers. It does not need to exist on a share. It can exist on my workstation. What happens is that Windows PowerShell reads the script file and converts the script into a script block. Then it executes that script block on the remote servers. So I only need a path that is accessible to my workstation. For this, I use my ubiquitous scratch folder named FSO. Here is the path to my script:

$filepath = "C:\fso\CreateScheduledTaskFolderAndTask.ps1"

   Note  The script I am executing is the exact script I wrote on Friday. I have not modified it in any way.

I use the Get-ADComputer cmdlet to query for all the computers in the serversorganizational unit. Here is that line of code:

$cn = Get-ADComputer -Filter * -SearchBase $searchBase 

   Note  The Get-ADComputer cmdlet is available from the Active Directory module. I obtained the Active Directory
   module on my workstation when I installed the Remote Server Administration Tools (RSAT). Versions of RSAT are
   operating system specific.

Now I walk through the collection of computer objects stored in the $cn variable, and I test my WinRm connection to the remote machine before I try to run the script. There is a Test-Connection cmdlet that sends a ping. The problem is that by default, ICMP packets are filtered in Windows Firewall; therefore, ping commands will fail. But I wanted to ensure that the remote computer was up and responding, so I use Test-WsMan instead. Here is that command:

Foreach ($n in $cn.name)

 {If(Test-WSMan -ComputerName $n -EA 0)

Finally, I use the Invoke-Command cmdlet to run my script on the remote machines. If the machine is not up (or not responding to Test-WsMan), I print the name of the remote computer that was not responding.

   Note  This command requires admin rights. I could supply alternate credentials if I needed to.

This could easily be modified to log to a file. Here is that command:

      {Invoke-Command -ComputerName $n -FilePath $filepath}

  ELSE {"$n is not available"} }

As shown here, I use Remote Desktop to connect to one of the remote servers to look at the Task Scheduler:

Image of menu

Here is the complete script:

$searchBase = "ou=servers,dc=nwtraders,dc=com"

$filepath = "C:\fso\CreateScheduledTaskFolderAndTask.ps1"

$cn = Get-ADComputer -Filter * -SearchBase $searchBase

Foreach ($n in $cn.name)

 {If(Test-WSMan -ComputerName $n -EA 0)

     {Invoke-Command -ComputerName $n -FilePath $filepath}

  ELSE {"$n is not available"} }

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

Ed Wilson, Microsoft Scripting Guy

PowerTip: Test Connection to Remote Server

$
0
0

Summary: Use Windows PowerShell to test the connection to a remote server.

Hey, Scripting Guy! Question How can I test the connection in my server to see if I can run a remote Windows PowerShell command?

Hey, Scripting Guy! Answer Use the Test-WsMan cmdlet, for example:

Test-WsMan –computername s1

Working with Dates in PowerShell

$
0
0

Summary: Microsoft Scripting Guy, Ed Wilson, talks about the fundamentals of working with dates in Windows PowerShell.

Microsoft Scripting Guy, Ed Wilson, is here. For as long as I can remember, I have pretty much always hated working with dates and times. Back on my Osborne One, it was no fun. The Atari did not make it any better; neither did my first IBM-compatible PCs.

But you know, I am probably not the only one who dislikes working with dates and times—that must be one reasons there are so many ways of formatting the silly things. I mean, there must be nearly a hundred different ways (I am not exaggerating too much). And not only that—if I dislike all of the standard ways of formatting the dates and times, I can always invent another one.

The problem is that a date and a time are composites; that is, they are objects. In Windows PowerShell, there is a standard .NET Framework object that is used: the System.DateTime object. MSDN documents lots of methods and properties for this object (for more information, see DateTime Structure). This is a good thing. In fact, it is a very good thing because it makes working with dates and times a lot easier.

A date is made up of not only year, month, and day. It also includes a day of the week and even a day of the year. These are all properties of the System.DateTime object.

A time is made up of hour, minute, and second. But not only that—it is also made up of milliseconds and ticks. These are also properties of the System.DateTime object.

The nice thing about having a DateTime object is that I can access each part of the date or the time as a single property of the object. In the old days (and one reason I hated dates and times so much), the date or the time would return as a string—or even as a series of strings. I then had to parse the string to find what the hour was, or I had to concatenate a string to express a complete date or time.

Not only that. The math was not standard either. I could not simply add several times together because I might end up with something really weird. The same thing held true for subtracting times from one another (such as when I have two time stamps and I want to see how long a process ran).

Dates and times are everywhere. They are present as the system time on a computer—and that controls things such as logging to the event log and timestamps for files, software installation, user management, auditing, and other security related tasks. From a basic reporting standpoint, I need to be able to work with dates and times whenever I work with any of those things.

The good news is that with the System.DateTime object, working with dates and times is a breeze. The first step, however, is to obtain an instance of a DateTime object.

Obtaining a DateTime object

This is really easy. All I need to do is to type Get-Date, and voila! I have an instance of the DateTime object. As shown here, it displays basic information to the console: the day of the week, the month, day, year, hour, minute, second, and A.M. or P.M.:

   PS C:\> Get-Date

Thursday, January 15, 2015 7:41:18 PM

   Note  One of the really great things about Windows PowerShell is that it always uses the local cultural information
   to control the way the Get-Date cmdlet returns the default information. Changing cultural settings changes the way
   the date and time display.

If I want to see the values of all of the properties of the System.DateTime object, I can pipe the results of Get-Date to the Format-List cmdlet. I select all of the properties (via a wild card character) and use the –Force parameter to tell it to display any hidden properties. This command and its output are shown here:

   PS C:\> Get-Date | format-list * -Force 

DisplayHint : DateTime

DateTime    : Thursday, January 15, 2015 7:44:33 PM

Date        : 1/15/2015 12:00:00 AM

Day         : 15

DayOfWeek   : Thursday

DayOfYear   : 15

Hour        : 19

Kind        : Local

Millisecond : 196

Minute      : 44

Month       : 1

Second      : 33

Ticks       : 635569478731960307

TimeOfDay   : 19:44:33.1960307

Year        : 2015

From this list of properties, I can easily choose any one property to display. I can do this by using the Select-Object cmdlet. To do this, I pipe the results from Get-Date by using the pipe character( | ):

   PS C:\> Get-date | Select-Object date

Date                                                                                 

----                                                                                  

1/15/2015 12:00:00 AM     

Notice that the output not only contains the date, but it also displays the time (midnight). Another way of obtaining the date is to use parenthesis around the Get-Date cmdlet. By using dotted notation, you will return only the date property:

   PS C:\> (Get-Date).Date

Thursday, January 15, 2015 12:00:00 AM

Once again, it returns both the date and the time of midnight. The best way (and indeed the easiest way) to return only the date is to use the –DisplayHint parameter and choose Date:

   PS C:\> get-date -DisplayHint Date

Thursday, January 15, 2015

That is all there is to working with dates in Windows PowerShell. Dates and Times Week will continue tomorrow when I will talk about creating a specific date.

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

Ed Wilson, Microsoft Scripting Guy 

PowerTip: Use PowerShell to Show Time

$
0
0

Summary: Use Windows PowerShell to show the current time.

Hey, Scripting Guy! Question How can I use Windows PowerShell to easily display only the current time?

Hey, Scripting Guy! Answer Use the Get-Date cmdlet and choose the Time display hint:

Get-Date -DisplayHint Time

Use PowerShell to Work with Individual Dates

$
0
0

Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to work with dates.

Microsoft Scripting Guy, Ed Wilson, is here. I don’t know about you, but one thing about my life as the Scripting Guy is that it keeps me busy. "Keeping busy" is a slang expression that means, "Dude, you are swamped."

The Scripting Wife and I just spent most of last week planning events for the remainder of 2015. Yep, my year is pretty well planned out. Not because I love being super organized. In fact, my default behavior is rather the opposite—I prefer a more natural, organic schedule. But the only way I can get to everything is if I have a plan.

This means that I spend a lot of time with dates and calendars. Actually, the Scripting Wife is the one who keeps up with that stuff because she really is organized. In fact, I have seen more than one tweet or Facebook post that said something to the effect that if you want me to do something, you better organize it with the Scripting Wife. She is great. Anyway…

One of the really cool things about Windows PowerShell is that it makes it easy for me to see what day the week a specific date will occur. It also makes it pretty easy for me to see how many days remain until a specific date occurs. There are several ways I can create dates.

Yesterday I talked a little bit about System.DateTime objects. If I create a specific date, instead of just returning today's date, I am creating a DateTime object that represents a date in the future or the past. One way to create a specific date is to use the Get-Date cmdlet and then specify values for the –Day, –Month, and –Year parameters. For example, you may know that William Shakespeare died on April 23, 1616. However, most people do not know that that was a Saturday. Here is how I found out that bit of trivia:

PS C:\> Get-Date -Month 4 -Day 23 -Year 1616

Saturday, April 23, 1616 2:20:19 PM

When I use Get-Date in this way, it returns a DateTime object (of course), but it is interesting that because I did not specify a time portion of the DateTime object, it uses my local system time. So, I ran the command above at 2:20:19 PM.

The Get-Date cmdlet will also accept a DateTime object as input. I found this out by looking at the syntax of the command. When I use Get-Help to look at the syntax, I see that the –Date parameter accepts <DateTime> for input. This tells me that the input value is expected to be an instance of the System.DateTime object. This is shown here:

PS C:\> (Get-Help get-date).syntax

Get-Date [[-Date] <DateTime>] [-Day <Int32>] [-DisplayHint <DisplayHintType>] [-Format <String>] [-Hour

<Int32>] [-Millisecond <Int32>] [-Minute <Int32>] [-Month <Int32>] [-Second <Int32>] [-Year <Int32>]

[<CommonParameters>]

Get-Date [[-Date] <DateTime>] [-Day <Int32>] [-DisplayHint <DisplayHintType>] [-Hour <Int32>]

[-Millisecond <Int32>] [-Minute <Int32>] [-Month <Int32>] [-Second <Int32>] [-UFormat <String>] [-Year

<Int32>] [<CommonParameters>]

Because Windows PowerShell expects a DateTime object for input to the –Date parameter, it will be happy with anything that I supply to the parameter that it can convert into an instance of a DateTime object. This is because Windows PowerShell does automatic type conversion. So anything that is reasonably formatted will be converted.

To manually convert a string that represents a date into a DateTime object, I can use the type accelerator, [DateTime], and it will convert (cast) the string to the object. Here is an example:

PS C:\> [datetime]"June 15, 1215"

Monday, June 15, 1215 12:00:00 AM

To prove that I actually converted the string to an instance of the System.DateTime object, I can pipe the results into the Get-Member cmdlet, for example:

[datetime]"June 15, 1215" | Get-Member 

I can also use the GetType method directly from the expression. This technique is shown here:

PS C:\> ([datetime]"June 15, 1215").GetType()

IsPublic IsSerial Name                            BaseType                                       

-------- -------- ----                                     --------                                       

True     True     DateTime                    System.ValueType                               

So, because I can convert a string to a DateTime object, and because the Get-Date cmdlet accepts a DateTime object as input, I have seen people do something like the following:

Get-date -date ([datetime]"June 15, 1215")

This works, but dude, it is a lot of extra work. In fact, it does not do any more than the previous expression. So how does Get-Date“June 15, 1215” actually work?

Well, the default parameter of Get-Date is actually –Date. And as I said earlier, it expects a DateTime object, and therefore it will try to convert whatever I give it into a DateTime object. I can see that –Date is the default parameter by using the Get-Help cmdlet. This is shown here:

PS C:\> Get-Help get-date -Parameter date

-Date <DateTime>

    Specifies a date and time. By default, Get-Date gets the current system date and time.

    Type the date in a format that is standard for the system locale, such as dd-MM-yyyy (German

    [Germany]) or MM/dd/yyyy (English [United States]).

    Required?                    false

    Position?                    1

    Default value                Current date

    Accept pipeline input?       True (ByValue, ByPropertyName)

    Accept wildcard characters?  false

Windows PowerShell is pretty good when it comes to converting my input date value. Here are some examples that it translates into a DateTime object:

PS C:\> get-date 6-15-1215

Monday, June 15, 1215 12:00:00 AM

PS C:\> get-date 6/15/1215

Monday, June 15, 1215 12:00:00 AM

PS C:\> get-date 6.15.1215

Monday, June 15, 1215 12:00:00 AM

It will even accept abbreviations. Here is an example of using an abbreviation:

PS C:\> get-date "Jun. 15, 1215"

Monday, June 15, 1215 12:00:00 AM

But if I do not use quotation marks, I get an error message. This is shown here:

PS C:\> get-date Jun. 15, 1215

Get-Date : Cannot bind parameter 'Date'. Cannot convert value "Jun." to type "System.DateTime". Error:

"String was not recognized as a valid DateTime."

At line:1 char:10

+ get-date Jun. 15, 1215

+          ~~~~

    + CategoryInfo          : InvalidArgument: (:) [Get-Date], ParameterBindingException

    + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.GetDateCommand

In addition, if I use the wrong symbol for a separator it generates an error message:

PS C:\> get-date 6\15\1215

Get-Date : Cannot bind parameter 'Date'. Cannot convert value "6\15\1215" to type "System.DateTime".

Error: "String was not recognized as a valid DateTime."

At line:1 char:10

+ get-date 6\15\1215

+          ~~~~~~~~~

    + CategoryInfo          : InvalidArgument: (:) [Get-Date], ParameterBindingException

    + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.GetDateCommand

Here is some fun trivia. If I do not remember how many days are in a month (such as February), I can wing it. So February 31, 2015 actually becomes March 3 (that is three days after the end of February, which is February 28. Here is what I am talking about:

PS C:\> get-date -Day 31 -Month 2 -Year 2015

Tuesday, March 3, 2015 3:24:06 PM

I thought, "Wow, that is pretty cool. I wonder if I can, say, add 30 days to February 15, and come up with something like March the 17?" So I tried it:

PS C:\> get-date -Day 45 -Month 2 -Year 2015

Get-Date : Cannot validate argument on parameter 'Day'. The 45 argument is greater than the maximum

allowed range of 31. Supply an argument that is less than or equal to 31 and then try the command again.

At line:1 char:15

+ get-date -Day 45 -Month 2 -Year 2015

+               ~~

    + CategoryInfo          : InvalidData: (:) [Get-Date], ParameterBindingValidationException

    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.GetDateCommand

Nope. The error message tells me that the maximum value of -Day is 31, which makes sense, I guess.

That is all there is to working with dates in Windows PowerShell. Date Time Week will continue tomorrow when I will talk about adding and subtracting days.

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

Ed Wilson, Microsoft Scripting Guy 

PowerTip: Use PowerShell to Find Day of Week

$
0
0

Summary: Learn how to use Windows PowerShell to find the day of the week.

Hey, Scripting Guy! Question How can I use Windows PowerShell to find which day of the week a specific date will occur?

Hey, Scripting Guy! Answer Use the Get-Date cmdlet, and specify day, month, and year parameters, for example:

Get-Date -Month 2 -Day 14 -Year 2015


Adding and Subtracting Dates with PowerShell

$
0
0

Summary: Microsoft Scripting Guy, Ed Wilson, talks about adding and subtracting dates with Windows PowerShell.

Microsoft Scripting Guy, Ed Wilson, is here. One of the things I really like about Windows PowerShell is the way it simplifies adding and subtracting from dates. For example, if I want to find users who haven’t logged in to the domain for 120 days, I need to be able to create a date that was 120 days ago. Then I need to get the date of their last log-in, and see if that date is more recent than 120 days ago.

I may need to do the same thing with the last time that files were accessed or to examine the date that print jobs were submitted to a print server. I may simply want to see all events from the security log that occurred within a specific date range. I may want to see how many days until a user's password expires so that I can warn them when the password comes within 10 days of expiring.

Whatever the need, quite often dates come into play. When I know how to create a specific DateTime object, whether in the past, in the future, or even for the present, I can use that DateTime object as an input parameter for other Windows PowerShell cmdlets.

There are six core Windows PowerShell cmdlets that accept DateTime objects as input parameters. These cmdlets are:

PS C:\> Get-Command -ParameterType [datetime] | ft -AutoSize

CommandType Name         ModuleName                    

----------- ----                     ----------                    

Cmdlet      Get-Date     Microsoft.PowerShell.Utility  

Cmdlet      Get-EventLog Microsoft.PowerShell.Management

Cmdlet      Get-Job      Microsoft.PowerShell.Core     

Cmdlet      New-TimeSpan Microsoft.PowerShell.Utility  

Cmdlet      Set-Date     Microsoft.PowerShell.Utility  

Cmdlet      Test-Path    Microsoft.PowerShell.Management

To find which parameters accept a DateTime object, I can use the Get-Help cmdlet and look at the syntax for the various parameter sets. This technique is shown here for the Test-Path cmdlet:

PS C:\> (Get-Help test-path).syntax

Test-Path [-Path] <String[]> [-Credential <PSCredential>] [-Exclude <String[]>]

[-Filter <String>] [-Include <String[]>] [-IsValid] [-PathType <TestPathType>]

[-UseTransaction [<SwitchParameter>]] [<CommonParameters>]

Test-Path [-Credential <PSCredential>] [-Exclude <String[]>] [-Filter <String>]

[-Include <String[]>] [-IsValid] [-PathType <TestPathType>] -LiteralPath

<String[]> [-UseTransaction [<SwitchParameter>]] [<CommonParameters>]

Test-Path [-NewerThan <DateTime>] [-OlderThan <DateTime>] [<CommonParameters>]

Adding dates and times—the easy way

If I want to add hours to a DateTime object, all I need to do is to create an instance of a DateTime object, and call the AddHours method. Here is an example using the Get-Date cmdlet:

PS C:\> (Get-Date).AddHours(2)

Friday, January 16, 2015 6:27:46 PM

I can also use an intermediate variable to hold the DateTime object and to call the method. This technique appears here:

PS C:\> $dte = Get-Date

PS C:\> $dte.AddHours(3)

Friday, January 16, 2015 7:29:00 PM

It is also possible to convert a string into a DateTime object by using the [dateTime] type accelerator. I first create a specific date and time, and then I call the AddHours method:

PS C:\> $dte = Get-Date

PS C:\> $dte.AddHours(3)

Friday, January 16, 2015 7:29:00 PM

If I want to add days, it is the same technique, but I call the AddDays method instead of AddHours. This technique is shown here by using the Get-Date cmdlet:

PS C:\> Get-Date

Friday, January 16, 2015 4:32:57 PM

PS C:\> (Get-date).AddDays(12)

Wednesday, January 28, 2015 4:33:00 PM

I can add lots of stuff to DateTime objects. Here is a list of the various Add methods.

PS C:\> Get-date | Get-Member -MemberType Method -Name a*

   TypeName: System.DateTime

Name            MemberType Definition                           

----            ---------- ----------                           

Add             Method     datetime Add(timespan value)         

AddDays         Method     datetime AddDays(double value)       

AddHours        Method     datetime AddHours(double value)      

AddMilliseconds Method     datetime AddMilliseconds(double value)

AddMinutes      Method     datetime AddMinutes(double value)    

AddMonths       Method     datetime AddMonths(int months)       

AddSeconds      Method     datetime AddSeconds(double value)    

AddTicks        Method     datetime AddTicks(long value)        

AddYears        Method     datetime AddYears(int value)     

If I want to create a DateTime object that represents a date in the past, I still use the appropriate Add method, but I supply a negative number. So in the following example, I create a DateTime object that is 12 days in the past:

PS C:\> Get-Date

Friday, January 16, 2015 4:34:53 PM

PS C:\> (Get-Date).adddays(-12)

Sunday, January 4, 2015 4:35:12 PM

The technique works exactly the same way for subtracting hours. Here, I create a DateTime object that is five hours in the past:

PS C:\> Get-Date

Friday, January 16, 2015 4:36:24 PM

PS C:\> (Get-Date).AddHours(-5)

Friday, January 16, 2015 11:36:46 AM

I can even combine methods, so I do not have to add -1 day and then add -2 hours by using intermediate expressions (unless I want to). Here is an example of using intermediate expressions:

$dte = Get-Date

$dte = $dte.AddDays(-1)

$dte = $dte.AddHours(-2)

$dte

But I can simplify this into a single line as shown here:

PS C:\> ((Get-Date).AddDays(-1)).addhours(-2)

Thursday, January 15, 2015 2:42:28 PM

The advantage of using the intermediate expressions is it is probably easier to read.

Some fun with DateTime objects

Because it is so easy to use WMI to find the remaining runtime on a laptop battery, and it is so easy to add minutes, I created a simple script to let me know when my laptop will shut down. I use the Get-CimInstance cmdlet to retrieve the Win32_Battery WMI class. I then choose the EstimatedRunTime property (which displays in minutes remaining on the battery), and I store the result in the $MinutesRunTime variable.

I then use the AddMinutes method from the DateTime object that I get from Get-Date, and I display the result. Because I want to perform the date calculation before I display the string, I use the subexpression $() to force the evaluation of the expression first. Here is the script:

$MinutesRunTime = (Get-CimInstance win32_battery).EstimatedRunTime

"The laptop will shut down at $((Get-Date).AddMinutes($MinutesRunTime))"

Note  I only have an instance of Win32_Battery if I am using a laptop or other portable device (such as a Microsoft Surface). Also, if I am plugged in and charging, it does not display accurate results.

That is all there is to adding and subtracting dates. Date Time Week will continue tomorrow when I will talk about more cool stuff.

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

Ed Wilson, Microsoft Scripting Guy 

PowerTip: Use PowerShell to Display Format for Short Date

$
0
0

Summary: Use Windows PowerShell to display the culture-specific format for a short date.

Hey, Scripting Guy! Question How can I use Windows PowerShell to display the format of a short date that is specific to the culture settings
           of my system?

Hey, Scripting Guy! Answer Use the Get-Culture cmdlet and select the DateTimeFormat and ShortDatePattern properties:

(Get-Culture).DateTimeFormat.ShortDatePattern

Formatting Date Strings with PowerShell

$
0
0

Summary: Microsoft Scripting Guy, Ed Wilson, talks about formatting date strings with Windows PowerShell.

Microsoft Scripting Guy, Ed Wilson, is here. It seems that different ways to display dates and times are in great supply. In fact, there are dozens of ways to do this. If I decide that I do not like the way a date or time displays, I can change it. In addition, the way a particular date style displays in one country is different than the way it displays in another country.

These differences are part of the culture settings. For example, the output from the Get-Date cmdlet appears differently depending on the UI culture settings. Here is an example:

PS C:\> Use-Culture de-de {get-date}

Mittwoch, 21. Januar 2015 12:23:40

PS C:\> Get-Date

Wednesday, January 21, 2015 12:23:45 PM

   Note  The Use-Culture function is not standard in Windows PowerShell or Windows. It comes from Lee Holmes’  
   PowerShell Cookbook module. I installed it from the PowerShell Gallery, but it is also available on PoshCode.

In general, I want the date to automatically change the way it displays based on culture settings because it helps avoid confusion. There may be times when I want to override this behavior. I can do this by directly formatting the date. I can use the ToStringmethod and specify the display pattern. The pattern MM – dd –yyyy specifies that I want the month, day, and year to appear in that order. The MM is case sensitive. Here is an example:

PS C:\> (Get-Date -Month 2 -Day 12 -Year 2015).tostring("MM-dd-yyyy")

02-12-2015

There can be a very real problem with this technique. In many regions, the day value comes first. So is the month February or is it December? Here is how the date displays when I use German UI culture settings:

PS C:\> Use-Culture de-DE {(Get-Date -Month 2 -Day 12 -Year 2015).tostring("MM-dd-yyyy")}

02-12-2015

According to their pattern, this is December 2, 2015. Here is the short date pattern:

PS C:\> [System.Globalization.CultureInfo]::GetCultureInfo(1031).DateTimeFormat.ShortDatePattern

dd.MM.yyyy

Now the culture settings use a hexadecimal value from the National Language Support API. Germany uses a hex value of 0x0407. If I convert it to a decimal format, it becomes 1031. This is shown here:

PS C:\> 0x0407

1031

I double check that I have the correct language settings by using the GetCulturalInfo static method:

PS C:\> [System.Globalization.CultureInfo]::GetCultureInfo(1031)

LCID             Name             DisplayName                                                    

----                 ----                  -----------                                                     

1031             de-DE            German (Germany)      

So if I really want to display a short date, I need to use a format specifier to tell Windows PowerShell to display a short date. In this way, it will be culture specific. On the MSDN page, Standard Date and Time Format Strings, I learn that the .NET short date specifier is “d”. So, I use the –format parameter of Get-Date, and the following appears:

PS C:\> get-date -Format d

1/21/2015

But what about using a different culture? Well, this is how it displays in culture de-DE:

PS C:\> Use-Culture de-DE {get-date -Format d}

21.01.2015

As a best practice, I should avoid creating my own date format strings if at all possible. If I use the built-in .NET date format specifiers, Windows PowerShell automatic displays it in the correct format. Here is a table of the .NET date format specifiers.

Format Specifier

Description

Examples

d

Short date pattern

2009-06-15T13:45:30 -> 6/15/2009 en-US

2009-06-15T13:45:30 -> 15/06/2009 fr-FR

2009-06-15T13:45:30 -> 2009/06/15 ja-JP

D

Long date pattern

2009-06-15T13:45:30 -> Monday, June 15, 2009 en-US

2009-06-15T13:45:30 -> 15 июня 2009 г. ru-RU

2009-06-15T13:45:30 -> Montag, 15. Juni 2009 de-DE

f

Full date pattern with short time pattern

2009-06-15T13:45:30 -> Monday, June 15, 2009 1:45 PM en-US

2009-06-15T13:45:30 -> den 15 juni 2009 13:45 sv-SE

2009-06-15T13:45:30 -> Δευτέρα, 15 Ιουνίου 2009 1:45 μμ el-GR

F

Full date pattern with long time pattern

2009-06-15T13:45:30 -> Monday, June 15, 2009 1:45:30 PM en-US

2009-06-15T13:45:30 -> den 15 juni 2009 13:45:30 sv-SE

2009-06-15T13:45:30 -> Δευτέρα, 15 Ιουνίου 2009 1:45:30 μμ el-GR

g

General date pattern with short time pattern

2009-06-15T13:45:30 -> 6/15/2009 1:45 PM en-US

2009-06-15T13:45:30 -> 15/06/2009 13:45 es-ES

2009-06-15T13:45:30 -> 2009/6/15 13:45 zh-CN

G

General date pattern with long time pattern

 2009-06-15T13:45:30 -> 6/15/2009 1:45:30 PM en-US

2009-06-15T13:45:30 -> 15/06/2009 13:45:30 es-ES

2009-06-15T13:45:30 -> 2009/6/15 13:45:30 zh-CN

M, m

Month/day pattern

2009-06-15T13:45:30 -> June 15 en-US

2009-06-15T13:45:30 -> 15. juni da-DK

2009-06-15T13:45:30 -> 15 Juni id-ID

O, o

Round-trip date/time pattern

2009-06-15T13:45:30  --> 2009-06-15T13:45:30.0000000-07:00

2009-06-15T13:45:30 --> 2009-06-15T13:45:30.0000000Z

2009-06-15T13:45:30 2009-06-15T13:45:30.0000000

2009-06-15T13:45:30-07:00 --> 2009-06-15T13:45:30.0000000-07:00

R, r

RFC1123 pattern

2009-06-15T13:45:30 -> Mon, 15 Jun 2009 20:45:30 GMT

s

Sortable date/time pattern

2009-06-15T13:45:30 -> 2009-06-15T13:45:30

2009-06-15T13:45:30 -> 2009-06-15T13:45:30

t

Short time pattern

2009-06-15T13:45:30 -> 1:45 PM en-US

2009-06-15T13:45:30 -> 13:45 hr-HR

2009-06-15T13:45:30 -> 01:45 ar-EG

T

Long time pattern

2009-06-15T13:45:30 -> 1:45:30 PM en-US

2009-06-15T13:45:30 -> 13:45:30 hr-HR

2009-06-15T13:45:30 -> 01:45:30 م ar-EG

u

Universal sortable date/time pattern

2009-06-15T13:45:30 -> 2009-06-15 20:45:30Z

U

Universal full date/time pattern

2009-06-15T13:45:30 -> Monday, June 15, 2009 8:45:30 PM en-US

2009-06-15T13:45:30 -> den 15 juni 2009 20:45:30 sv-SE

2009-06-15T13:45:30 -> Δευτέρα, 15 Ιουνίου 2009 8:45:30 μμ el-GR

Y, y

Year month pattern

2009-06-15T13:45:30 -> June, 2009 en-US

2009-06-15T13:45:30 -> juni 2009 da-DK

2009-06-15T13:45:30 -> Juni 2009 id-ID

That is all there is to using .NET date format specifiers. Date Time Week will continue tomorrow when I will talk about more cool stuff.

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

Ed Wilson, Microsoft Scripting Guy

PowerTip: Use PowerShell to Display date Format for Specific Culture

$
0
0

Summary: Learn how to use Windows PowerShell to display date formatting for a specific culture.

Hey, Scripting Guy! Question How can I use Windows PowerShell to see the short date pattern for a specific culture without
           changing my UI culture settings?

Hey, Scripting Guy! Answer Use the CultureInfo class from System.Globalization, call the GetCultureInfo static method
           while passing a culture number, and choose the ShortDatePattern property from the DateTime 
           format object, for example:

[System.Globalization.CultureInfo]::GetCultureInfo(1031).DateTimeFormat.ShortDatePattern

Create Custom Date Formats with PowerShell

$
0
0

Summary: Microsoft Scripting Guy, Ed Wilson, talks about creating custom date formats with Windows PowerShell.

Microsoft Scripting Guy, Ed Wilson, is here. One of the cool things about working with Windows PowerShell is that it is highly configurable. In short, if there is something that I do not like, I can change it. Most of the time, that change is relatively simple to make. So when working with dates and times, there are lots of standardized ways of displaying the information.

            Note  Also see Formatting Date Strings with PowerShell.

But if one of these standardized ways doesn’t work out, I am not stuck. I can use the UFormat parameter to change the output to my needs. Keep in mind, that any formatting of the date/time output changes it from a DateTime object to a string. This means that I want to make sure I make calculations and computations with my date as an object before I output it as a string.

The UFormat parameter uses Unix date formatting strings. I can, for example, display the date and the time by using the cstring. Keep in mind that these are case sensitive, and I proceed them with the percentage sign. So, to display an abbreviated day of the week and month name, followed by the day of the month, the time, and the year, I use %c. This is shown here:

PS C:\> get-date -UFormat %c

Thu Jan 22 15:39:36 2015

The cool thing is that for this command, I do not need to use quotation marks because Windows PowerShell expects me to supply a formatting string.

I can also display a standard date output with respect to the local culture settings, but it does not appear to work properly. So I use the .NET formatting specifiers for this. This is shown here:

PS C:\> Use-Culture de-DE {get-date -UFormat %x}

01.22.15

PS C:\> Use-Culture de-DE {get-date -Format d}

22.01.2015

By using the UFormat codes, I can also control the way time outputs. For example, as shown here, I can display the time in 12-hour format by using %r.

PS C:\> get-date -UFormat %r

04:33:09 PM

I can also display a 24-hour format. A capital R outputs the hour and minute as shown here:

PS C:\> get-date -UFormat %R

16:33

If I want to output the hour, minute, and seconds in 24-hour format, I use either capital T or capital X as shown here:

PS C:\> get-date -UFormat %T

16:35:23

PS C:\> get-date -UFormat %X

16:35:27

Most of the time when I use the UFormat strings, however, it is because I want to customize my output string. They are very flexible. I choose the parts of the date and time that I want to output. For example, suppose I need the year in four digits, month, day, hours in 24-hour format, minutes, and seconds, and I want them separated by an underscore:

PS C:\> get-date -UFormat "%Y_%m_%d_%H_%M_%S"

2015_01_22_16_44_07

As you can see, there is a lot of flexibility. In fact, I can format the date and time any way that I can imagine.

Here is a table that documents the Unix format strings.

            Note  These letter codes are case sensitive.

Letter code

Meaning

Example

c

Date and time

Fri Jun 16 10:31:27 2015

D

Date in mm/dd/yy format

06/14/06

x

Date in standard format for locale

09/12/15 for English-US

C

Century

20 for 2015

Y, G

Year in 4-digit format

2015

y, g

Year in 2-digit format

15

b, h

Month name - abbreviated

Jan

B

Month name - full

January

m

Month number

06

W, U

Week of the year - zero based

00-52

V

Week of the year - one based

01-53

a

Day of the week - abbreviated name

Mon

A

Day of the week - full name

Monday

u, w

Day of the week - number

Monday = 1

d

Day of the month - 2 digits

05

e

Day of the month - digit preceded by a space

 5

j

Day of the year

1-366

p

AM or PM

 PM

r

Time in 12-hour format

09:15:36 AM

R

Time in 24-hour format - no seconds

17:45

T, X

Time in 24 hour format

17:45:52

Z

Time zone offset from Universal Time Coordinate UTC

07

H, k

Hour in 24-hour format

17

I, l

Hour in 12 hour format

05

M

Minutes

35

S

Seconds

05

s

Seconds elapsed since January 1, 1970

00:00:00 1150451174.95705

n

newline character

\n

t

Tab character

\t

That is all there is to using UFormat strings to format dates. That is also the end of Date Time Week. Join me tomorrow when I will talk about the changing nature of documentation.

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

Ed Wilson, Microsoft Scripting Guy

PowerTip: Pipe String to Get-Date

$
0
0

Summary: Pipe a string to the Windows PowerShell Get-Date cmdlet to convert it to a DateTime object.

Hey, Scripting Guy! Question How can I use Windows PowerShell to convert a date that is in a string format to a DateTime object?

Hey, Scripting Guy! Answer Create a pipeline, for example:

"11/14/2015" | get-date 

Weekend Scripter: The Changing Nature of Documentation

$
0
0

Summary: Microsoft Scripting Guy, Ed Wilson, talks about the changing nature of documentation.

Microsoft Scripting Guy, Ed Wilson, is here. This week, we announced Microsoft HoloLens during the Windows 10: The Next Chapter webcast. I mean, I want one—badly.

This is going to be an incredible year. The excitement of holographic computing has me thinking about Star Trek. Of course last year, we introduced a holodeck—so the future is now, so to speak.

But then I was thinking, "Does one ship a stack of books along with the HoloLens?" It doesn’t make sense, I suppose. Back when we shipped Windows NT 3.51, there were books and books and books of documentation for the product. I mean, stacks of disks and stacks of books. Here is a picture I had our archives people dig up:

Image of books

In fact, when I bought my first computer (an Osborn 1), it came with lots of books. My most recent laptop purchase, however, did not come with anything but a stack of legal disclaimers. My toothbrush came with more documentation. (Actually, I was wondering about toothbrush documentation, and I did a quick Bing search. 7,500,000 pages returned, including YouTube videos and pages of documentation from the Centers for Disease Control and Prevention.)

Anyway, I did not bother to read all that stuff, and usability studies found that most people did not bother to read it either.

When I get ready to install and configure a new software application, I do not want to read through a bunch of marketing stuff telling me how great the software is. Dude, I already bought it. What I want is a quick start guide that tells me exactly what I need to do to quickly get the thing up and running. But that is just me. Other people prefer (in fact, they need) a features guide to tell them what features are available. Others need marketing material so they can help sell the application to their management. Still other people are visual learners, and they need a picture, a diagram, or a video that shows them exactly how to configure the application.

As far as I am concerned, images are great. I also like samples of working code. I still have nightmares about some documentation that says: To print, click the Print button from the Print menu. But when I look at the application, I cannot find the Print menu. I mean clicking the Print button would be an obvious choice, but where is the silly thing hidden? And the documentation didn’t tell me.

Many times, I want to hear real advice from people who use the product for a living. This is why I love blogs so much. In the Windows PowerShell world, most of the MVPs maintain blogs, or they contribute to blogs.

In the old days, documentation was pretty much a book that came as a big box of disks. Today, documentation is much more customized, and it comes in many forms. In fact, documentation comes in the form of wiki articles, blog posts, videos, webcasts, discussion forums, and various forms of social media. The cool thing is that I can find exactly what I need pretty much when I need it. All I need is access to a search engine and the Internet—which is pretty much all of the time.

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

Ed Wilson, Microsoft Scripting Guy 


PowerTip: View PowerShell Help Online

$
0
0

Summary: View Windows PowerShell cmdlet Help online.          

Hey, Scripting Guy! Question How can I view Windows PowerShell Help in my web browser?

Hey, Scripting Guy! Answer The –Online parameter with the Get-Help cmdlet opens the latest online Windows PowerShell Help
            in your web browser, for example:

Get-Help Get-Command -Online

2014 Honorary Scripting Guys Announced

$
0
0

Summary: The Honorary Scripting Guys for 2014 are announced.

Microsoft Scripting Guy, Ed Wilson, is here. I have been pretty busy, with missing work because of my ear surgery and the holidays and all, so I enlisted the help of the Scripting Wife, Teresa, to write the latest Honorary Scripting Guys post. I gave her the names and she did the rest. So here's Teresa...

Hello everyone,

You know that I do not try to hide things about myself nor do I try to embellish my qualities—I am what I am. I have strong points and weak points. Writing is not one of my strong points and repetition is one of the most useless things all around, in my opinion. So I am going to start by snagging some of Ed’s words from two years ago and reuse them:

What does it take to become an official Honorary Scripting Guy? It takes an extreme commitment to the scripting community, a remarkable dedication helping to spread the good word about Windows PowerShell, and a relentless pursuit of excellence in producing exceptional content. To read more about the Honorary Scripting Guys, see:

Image of Scripting Guy

Which brings us up-to-date. Now without much delay, I am happy to introduce you to three new Honorary Scripting Guys:

  • Ian Farr
  • Ashley McGlone
  • Gary Siepser

Here is a little more information about the new Honorary Scripting Guys. If you click the link on their names, it will take you to their Hey, Scripting Guy! Blog posts.

Ian Farr

Ian is a Microsoft premier field engineer (PFE). He started writing UNIX shell scripts to automate simple tasks. Then as a Windows IT pro, he discovered VBScript, and it ignited a passion for automation. Over the years, he has used batch files, KiXtart, JScript, HTAs, Perl, JavaScript, and Python. Ian loves solving problems with scripts, and he has written code for several large enterprise environments. As a premier field engineer at Microsoft, he teaches Windows PowerShell and helps customers with their own scripts.

Photo of Ian Farr

Ashley McGlone

Ashley is a premier field engineer (PFE) for Microsoft. He started writing code on a Commodore VIC20 in 1982, and he has been hooked ever since. Today he specializes in Active Directory and Windows PowerShell, and he helps Microsoft Premier Customers reach their full potential through risk assessments and workshops. Ashley’s favorite workshop to teach is Windows PowerShell Essentials, and his TechNet blog focuses on real-world solutions for Active Directory by using Windows PowerShell.

Blog: Goatee PFE
Twitter: @GoateePFE

Gary Siepser:

Gary is a senior premier field engineer for Microsoft, specializing in everything PowerShell. These days, he teaches several Windows PowerShell classes to Microsoft customers. Check out Microsoft Premier Support Services to learn more.

Twitter @powerShellPFE

Ed also gave me a list of previous Honorary Scripting Guy recipients who have made a significant contribution to the Hey, Scripting Guy! Blog in 2014. If they were not already Honorary Scripting Guys, they would be!

Thanks to all the guest bloggers.

~Teresa 

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

Ed Wilson, Microsoft Scripting Guy 

PowerTip: Windows PowerShell Survival Guide

$
0
0

Summary: Find the Windows PowerShell Survival Guide. 

Hey, Scripting Guy! Question Where can I find a community-based resource that links to all the essentials?

Hey, Scripting Guy! Answer Check out the Windows PowerShell Survival Guide on the TechNet Wiki. It contains links to dozens of
           Windows PowerShell resources.

Understanding Numbers in PowerShell

$
0
0

Summary: Microsoft Scripting Guy, Ed Wilson, talks about numbers in Windows PowerShell.

Hey, Scripting Guy! Question Hey, Scripting Guy! One of the things that is frustrating to me with Windows PowerShell is the way that it handles numbers. For example, I want to know the percent of processor utilization for something, and it displays a number that is like fifty million numbers long. What is up with that? Why can’t Windows PowerShell just tell me something useful?

—SP

Hey, Scripting Guy! Answer Hello SP,

Microsoft Scripting Guy, Ed Wilson, is here. Today it is cold and raining outside. I decided to make a cup of red berry tea. It does not have any caffeine, and it seems to be just thing for a cold, rainy morning. I do not mix my own red berry tea—this is one of the teas that I buy already mixed. I still had a nice bag I brought back from Hamburg. Anyway, I am sitting here sipping a nice cup of red berry tea and I came across your email to scripter@microsoft.com. It is perfect because today I am kicking off Numbers Week.

There are many cmdlets and functions built-in to Windows PowerShell that display a formatted number. But there are other interfaces that return the raw number. The reason for this is that I may want to display information to 1, 2, 3, or even 5 decimal places, depending on what I am monitoring. In many cases, I work with the entire raw number so I can get a better view of what exactly might be taking place. For this reason, it makes sense to understand a bit about the types of numbers in Windows PowerShell.

Numeric types

There are many types of numbers in Windows PowerShell. Most of the time, I do not need to know anything about the different types of numbers because Windows PowerShell performs the type conversion behind the scenes. However, a good understanding of the types of numbers can be useful, and it is certainly useful from a troubleshooting perspective. There are actually three numeric types that Windows PowerShell uses:

  • Decimal types
  • Integral types
  • Floating-point types

Decimal types

Decimals are a 128-bit data type. Decimals can be positive or negative, and they are more precise than floating point types. Decimals are commonly used in financial or monetary calculations. A decimal is an instance of the System.Decimal .NET Framework type, and therefore, it has static properties I can use to determine the range. Here is the minimum and maximum range of the decimal numeric type:

PS C:\> [decimal]::MinValue

-79228162514264337593543950335

PS C:\> [decimal]::MaxValue

79228162514264337593543950335

This range is commonly expressed as (-7.9 x 1028 to 7.9 x 1028) / (100 to 28).

Integral types

Integral types come in the signed and the unsigned variety (except for the char, which is an 16-bit Unicode character). Integers range in size from 8-bit integers to 64-bit integers.

An sbyte is a signed 8-bit integer, and it ranges from -128 to 127. A byte is an unsigned 8-bit integer that ranges from 0 to 255. The following code illustrates this:

PS C:\> [byte]::MinValue

0

PS C:\> [byte]::MaxValue

255

PS C:\> [sbyte]::MinValue

-128

PS C:\> [sbyte]::MaxValue

127

A short is a signed 16-bit integer, and a ushort is an unsigned 16-bit integer. To obtain a short, I use the System.Int16 .NET Framework class, and to obtain a ushort, I use System.uInt16. I can use the [int16] and the [uint16] type accelerators for this purpose. The following code illustrates their ranges:

PS C:\> [int16]::MinValue

-32768

PS C:\> [int16]::MaxValue

32767

PS C:\> [uint16]::MinValue

0

PS C:\> [uint16]::MaxValue

65535

Int is the default numeric data type in Windows PowerShell. It is a 32-bit signed integer. The .NET Framework class is System.Int32. Because it is the default numeric data type, I can use [int32] or [int]. There is also an unsigned 32-bit integer. It is the System.uint32 .NET Framework type. I can use [uint32] to create an unsigned 32-bit integer. The ranges of these numbers are shown here:

PS C:\> [int32]::MinValue

-2147483648

PS C:\> [int32]::MaxValue

2147483647

PS C:\> [int]::MaxValue

2147483647

PS C:\> [uint32]::MinValue

0

PS C:\> [uint32]::MaxValue

4294967295

A long is a signed 64-bit integer and a ulong is an unsigned 64-bit integer. The .NET Framework classes are System.Int64 and System.uInt64. I can therefore use [int64] or [uint64] to create the long or the ulong data types. The following code illustrates the ranges of the long and ulong:

PS C:\> [int64]::MinValue

-9223372036854775808

PS C:\> [int64]::MaxValue

9223372036854775807

PS C:\> [uint64]::MinValue

0

PS C:\> [uint64]::MaxValue

18446744073709551615

Floating-point types

There are two floating-point types that Windows PowerShell uses: the float and the double. The float uses seven digits of precision and the double uses 15–16 digits of precision. The float type is an instance of the System.Single .NET Framework value type, and the double is an instance of the System.Double type. I can therefore use [single] and [double] to constrain numbers to these types. The following code illustrates their minimum and maximum values:

PS C:\> [single]::MinValue

-3.402823E+38

PS C:\> [single]::MaxValue

3.402823E+38

PS C:\> [double]::MinValue

-1.79769313486232E+308

PS C:\> [double]::MaxValue

1.79769313486232E+308

The following table summarizes the numeric value types, their ranges, sizes, and .NET Framework types.

Type

Range

Size or Precision

.NET Framework type

Decimal

(-7.9 x 1028 to 7.9 x 1028) / (100 to 28)

28 – 29 significant digits

System.Decimal

Sbyte

-128 to 127

Signed 8-bit

System.Sbyte

Byte

0 to 255

Unsigned 8-bit

System.Byte

Char

U+0000 to U+ffff

Unicode 16-bit

System.Char

Short

-32,768 to 32,767

Signed 16-bit

System.Int16

Ushort

0 to 65,535

Unsigned 16-bit

System.Uint16

Int

-2,147,483,648 to 2,147,483,647

Signed 32 bit

System.Int32

Uint

0 to 4,294,967,295

Unsigned 32-bit

System.Uint32

Long

9,223,372,036,854,775,808 to 9,223,372,036,854,775,807

Singed 64-bit

System.Int64

Ulong

0 to 18,446,744,073,709,551,615

Unsigned 64-bit

System.Uint64

Float

±1.5e−45 to ±3.4e38

7 digits

System.Single

Double

±5.0e−324 to ±1.7e308

15 – 16 digits

System.Double

That is all there is to using Windows PowerShell to format numbers, SP. Numbers Week will continue tomorrow when I will talk about more cool stuff.

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

Ed Wilson, Microsoft Scripting Guy 

PowerTip: Round Number Up or Down with PowerShell

$
0
0

Summary: Easily use Windows PowerShell to round a number up or down.  

Hey, Scripting Guy! Question I want only a whole number returned, so I want the number rounded up or down as appropriate.
           How can I do this with Windows PowerShell?

Hey, Scripting Guy! Answer Cast the number as an integer, and Windows PowerShell will round the number up or down
           as appropriate, for example:

PS C:\> [int]22.4

22

PS C:\> [int]22.5

22

PS C:\> [int]22.6

23

Viewing all 2129 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>