Quantcast
Channel: Hey, Scripting Guy! Blog
Viewing all 3333 articles
Browse latest View live

Learn to Use the PowerShell Variable: Drive

0
0

Summary: Microsoft Scripting Guy, Ed Wilson, talks about using the Windows PowerShell Variable: drive.

Hey, Scripting Guy! Question Hey, Scripting Guy! What is a Variable: drive? It sounds somewhat “iffy.”

—AS

Hey, Scripting Guy! Answer Hello AS,

Microsoft Scripting Guy, Ed Wilson, is here. The Charlotte Windows PowerShell User Group meeting last night was great. The Scripting Wife and I had a great time, as did the other attendees. Windows PowerShell MVP, Jim Christopher, and user group supporter, Brian Wilhite, continue to amaze me at how they manage the group. They are doing a fine job.

This morning I am listening to a CD that the Scripting Wife bought me of Segovia. Along with a nice cup of Gunpowder green tea with jasmine, it creates the perfect Windows PowerShell scripting environment (at least for me).

Access the Variable: drive to find variables

To access the Windows PowerShell Variable: drive, I can use the Get-ChildItem cmdlet and specify the drive name. I can do this from any location. This technique is shown here.

PS C:\> dir variable:

 

Name                           Value

----                           -----

$                              cls

?                              True

^                              cls

args                           {}

ConfirmPreference              High

<…Output Truncated…>

In general, however, when I am working with the Variable: drive, I set my working location to that drive as shown here.

PS C:\> cd variable:

PS Variable:\>

To see the variables that are defined in my session, I can use the Get-ChildItem cmdlet (dir, ls, and gci are aliases). This technique is shown here.

Image of command output

Modify variables by using the Variable: drive

To create a new variable, I can use the New-Item cmdlet. I must specify the name of the variable and the value to associate with it. This technique is shown here.

PS Variable:\> New-Item -Name sample -Value "sample value"

 

Name                           Value

----                           -----

sample                         sample value

To directly access the value, I call the variable with the $ (dollar sign) in front of the variable name. This is shown here.

PS Variable:\> $sample

sample value

However, if I use Get-Item to retrieve the variable, I do not use the dollar sign. This is shown here.

PS Variable:\> Get-Item sample

 

Name                           Value

----                           -----

sample                         sample value

To modify the value that is associated with the variable, I can use the Set-Item cmdlet as shown here.

PS Variable:\> Set-Item sample -Value "new sample value"

PS Variable:\> Get-Item sample

 

Name                           Value

----                           -----

sample                         new sample value

If I want to delete the variable, I use the Remove-Item cmdlet. This technique is shown here.

PS Variable:\> Get-Item sample | Remove-Item

I can also use the Remove-Item cmdlet directly (and not use the pipeline). This is shown here.

PS Variable:\> New-Item -Name sample -Value "sample value"

 

Name                           Value

----                           -----

sample                         sample value

 

PS Variable:\> Remove-Item sample

AS, that is all there is to using the Windows PowerShell Variable: drive. This also concludes Windows PowerShell Provider Week. Join me tomorrow for the Weekend Scripter when I will talk about finding dynamic parameters for your favorite Windows PowerShell cmdlets.

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: Easily Find the Value of a PowerShell Variable

0
0

Summary: Learn how to return only the value of a Windows PowerShell variable.

Hey, Scripting Guy! Question How can I use a Windows PowerShell cmdlet to return only the value of a particular variable?

Hey, Scripting Guy! Answer Use the Get-Variable cmdlet, and specify the name of the variable and the –valueonly switch. This technique is shown here using the home variable:

PS C:\> Get-Variable -Name home -ValueOnly

C:\Users\ed.IAMMRED

Weekend Scripter: Use PowerShell to Find Dynamic Parameters

0
0

Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to discover dynamic parameters for his favorite cmdlets.

Microsoft Scripting Guy, Ed Wilson, is here. I submitted my session for SQL Saturday in Atlanta, Georgia. To be honest, I was not going to do so because it is only two weeks prior to TechEd in New Orleans—but hey, there are a lot of cool people that attend SQL Saturday. I think we will probably have an all-day Windows PowerShell track at SQL Saturday in Atlanta. We did last year, and it was an absolute blast.  The question came up when I was on the PowerScripting podcast, and I have been mulling it over for a while. Finally, we decided to go. So the Scripting Wife and I will be at SQL Saturday in Atlanta (assuming they approve my session submission).

Playing around with Get-Command

Anyway, I was playing around with Windows PowerShell this morning, and I decided to go back and read the Help file content for Get-Command. I ran across the –ArgumentListparameter. I can use it to change the context for the Get-Command cmdlet. Cool.   

Note   I am constantly reading over the Help content for Windows PowerShell because I simply cannot remember everything about everything. There is a difference between reading content when looking for an answer to a particular problem and simply grazing. When I am looking for a specific answer, I find the answer and I leave to go solve my problem. When I am grazing, I take my time and sample a bit of everything. I believe both types of reading are necessary.

OK, so I use the Get-Command cmdlet and the –ArgumentListparameter to display the definition of the command. Unfortunately, the first attempt does not work too well as shown here.

PS C:\> Get-Command Get-ChildItem -ArgumentList cert: | select definition

 

Definition

----------

...

No problem; I know how to deal with this issue. I need to expand the object that is contained in the property. To do this, I use the Select-Object cmdlet and choose the –ExpandPropertyparameter. This results in a nice display of the parameter sets that are available when using the Get-Command cmdlet. These results are shown here.

PS C:\> Get-Command Get-ChildItem -ArgumentList cert: | select -expand definition

 

Get-ChildItem [[-Path] <string[]>] [[-Filter] <string>] [-Include <string[]>] [-Excl

ude <string[]>] [-Recurse] [-Force] [-Name] [-UseTransaction] [-CodeSigningCert] [-S

SLServerAuthentication] [-DnsName <DnsNameRepresentation>] [-Eku <string[]>] [-Expir

ingInDays <int>] [<CommonParameters>]

 

Get-ChildItem [[-Filter] <string>] -LiteralPath <string[]> [-Include <string[]>] [-E

xclude <string[]>] [-Recurse] [-Force] [-Name] [-UseTransaction] [-CodeSigningCert]

[-SSLServerAuthentication] [-DnsName <DnsNameRepresentation>] [-Eku <string[]>] [-Ex

piringInDays <int>] [<CommonParameters>]

Well that is a command to keep in the back of my mind. I can get a nice display of a cmdlet parameter set on a per-provider basis by using the Get-Command cmdlet. Sweet!

Now, I want to find only the parameters. To do this, I use the Select-Object cmdlet and choose parameters. The command and its output are shown here.

PS C:\> Get-Command Get-ChildItem -ArgumentList cert: | select parameters

 

Parameters

----------

{[Path, System.Management.Automation.ParameterMetadata], [LiteralPath, System.Man...

Ah, ha. The Parameters property returns an object—actually, a collection of objects. So once again, I will send the result to the ExpandProperty parameter. This is shown here.

PS C:\> Get-Command Get-ChildItem -ArgumentList cert: | select -ExpandProperty parameters

 

Key                                        Value

---                                        -----

Path                                       System.Management.Automation.Parameter...

LiteralPath                                System.Management.Automation.Parameter...

Filter                                     System.Management.Automation.Parameter...

Include                                    System.Management.Automation.Parameter...

Exclude                                    System.Management.Automation.Parameter...

Recurse                                    System.Management.Automation.Parameter...

Force                                      System.Management.Automation.Parameter...

Name                                       System.Management.Automation.Parameter...

Verbose                                    System.Management.Automation.Parameter...

Debug                                      System.Management.Automation.Parameter...

ErrorAction                                System.Management.Automation.Parameter...

WarningAction                              System.Management.Automation.Parameter...

ErrorVariable                              System.Management.Automation.Parameter...

WarningVariable                            System.Management.Automation.Parameter...

OutVariable                                System.Management.Automation.Parameter...

OutBuffer                                  System.Management.Automation.Parameter...

UseTransaction                             System.Management.Automation.Parameter...

CodeSigningCert                            System.Management.Automation.Parameter...

SSLServerAuthentication                    System.Management.Automation.Parameter...

DnsName                                    System.Management.Automation.Parameter...

Eku                                        System.Management.Automation.Parameter...

ExpiringInDays                             System.Management.Automation.Parameter...

Now the information is contained in a generic dictionary object. This means there are a number of additional methods and properties to deal with. Actually, I am only interested in the Keys property. So, I use the group and dot technique, and select only the Keys. This is shown here.

PS C:\> (Get-Command Get-ChildItem -ArgumentList cert: | select -ExpandProperty parameters).keys

Path

LiteralPath

Filter

Include

Exclude

Recurse

Force

Name

Verbose

Debug

ErrorAction

WarningAction

ErrorVariable

WarningVariable

OutVariable

OutBuffer

UseTransaction

CodeSigningCert

SSLServerAuthentication

DnsName

Eku

ExpiringInDays

Groovy. Now all I need to do is sort my list of properties so I can feed the results to Compare-Object. So, I back up a bit and I store the expanded parameters in a variable. I do this for the Certificate provider and for the FileSystem provider. These two commands are shown here.

PS C:\> $cert = Get-Command Get-ChildItem -ArgumentList cert: | select -ExpandProperty parameters

PS C:\> $file = Get-Command Get-ChildItem -ArgumentList c: | select -ExpandProperty parameters

Now, I want to sort the keys, and store the sorted list of keys in a variable. The following two commands do this for me.

PS C:\> $certKeys = $cert.Keys | sort

PS C:\> $filekeys = $file.Keys | sort

Now it is time to use the Compare-Object cmdlet to compare the two lists of provider-specific parameters for the Get-ChildItem cmdlet. This command is shown here.

Compare-Object -ReferenceObject $filekeys -DifferenceObject $certKeys

Following are the commands and the output associated with the commands.

Image of command output

If I keep my comparisons consistent—that is, I use the FileSystem provider as my ReferenceObject, and I use the other providers for the DifferenceObject, the output will be consistent. The SideIndicator => will always point to new parameters added by the different PS Provider. Because the returned difference object is a PSCUSTOM object, it means that SideIndicatoris a NoteProperty, and I can use it in a Where-Object statement. The following command returns only parameters added by DifferenceObject (my collection of Certificate provider-specific parameters).

PS C:\> Compare-Object -ReferenceObject $filekeys -DifferenceObject $certKeys | ? sideindicator -eq '=>'

 

InputObject                                SideIndicator

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

CodeSigningCert                            =>

DnsName                                    =>

Eku                                        =>

ExpiringInDays                             =>

SSLServerAuthentication                    =>

Comparing Get-ChildItem with the Registry provider

Any drive I pass to the –ArgumentListparameter causes Get-Command to return provider-specific parameters. Therefore, I can use HKLM: as my drive to return Registry provider parameters. The following code illustrates the technique.

$reg = Get-Command Get-ChildItem -ArgumentList hklm: | select –ExpandProperty parameters

$file = Get-Command Get-ChildItem -ArgumentList c: | select -ExpandProperty parameters

$regKeys = $reg.Keys | sort

$filekeys = $file.Keys | sort

 Compare-Object -ReferenceObject $filekeys -DifferenceObject $regKeys

When I run the command, the following output displays.

Image of command output

I can see from the previous output that there are no added parameters to Get-ChildItem when it is used on the registry drives. Instead, I see that a number of parameters are actually removed. This makes sense when reviewing the missing parameters: Attributes, Directory, File, Hidden, ReadOnly, and System. These are related to files and folders, not to registry keys.

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: Find Renamed PowerShell 3.0 Cmdlets

0
0

Summary: Use Windows PowerShell in Windows 8 or Windows Server 2012 to find renamed cmdlets.

Hey, Scripting Guy! Question You recently discovered that a cmdlet you had used on Windows Server 2008 R2 has been renamed in Windows Server 2012. Because an alias was created that mapped the old cmdlet name to the new cmdlet name, it took you awhile to discover the rename. How can you find all the renamed cmdlets?

Hey, Scripting Guy! AnswerUse the Get-Module cmdlet to find all installed modules and pipe the results to the Import-Module cmdlet (do this on a computer that has the RSAT installed). Now use the Get-Alias cmdlet with a wild card pattern to discover the renamed cmdlets with aliases that match old names. Finally, select the name of the alias (which shows the old cmdlet name) and the definition of the alias (which shows the new cmdlet name).

Get-Alias *-* | select name, definition

Weekend Scripter: Playing Around with PowerShell Modules

0
0

Summary: Microsoft Scripting Guy, Ed Wilson, talks about discovering cool information by playing around with Windows PowerShell modules.

Microsoft Scripting Guy, Ed Wilson, is here. It is the weekend here in Charlotte, North Carolina in the United States. I am sipping a cup of oolong green tea with a bit of jasmine and cinnamon stick, and eating some fresh strawberries that the Scripting Wife found. I am listening to Traffic on my laptop, I have my Windows PowerShell console open, and I am playing around with modules.

Modules that have nested modules

The first thing to do when playing with module information is to import all of the modules. The easy way to do this is to use Get-Module (gmo is an alias) to get the modules, and then pipe the module info to the Import-Module cmdlet (ipmo is an alias). This command is shown here.

gmo -ListAvailable | ipmo

After I have imported all of the modules, I can use the Get-Module cmdlet to find modules that have nested modules. To do this, I look for values in the NestedModulesproperty. This command is shown here.

Get-Module | ? nestedmodules | select name, nestedmodules

The command and its associated output are shown here.

Image of command output

To find out how many modules have nested modules, I pipe the results to the Measure-Object cmdlet as shown here.

PS C:\> Get-Module | ? nestedmodules | select name, nestedmodules | measure

Count    : 55

Average  :

Sum      :

Maximum  :

Minimum  :

Property :

To see how many modules I have loaded, I use the Get-Module cmdlet and pipe the results to the Measure-Object cmdlet. This is shown here.

PS C:\> Get-Module | measure

Count    : 81

Average  :

Sum      :

Maximum  :

Minimum  :

Property :

Finding numbers of exported commands

To find the number of exported commands from a cmdlet, I need to count how many cmdlets exist in the ExportedCommandsproperty. I can directly access the ExportedCommandsproperty by grouping the results of the command. This is shown here.

PS C:\> (Get-Module bestpractices).exportedcommands

Key                                        Value

---                                        -----

Get-BpaModel                               Get-BpaModel

Get-BpaResult                              Get-BpaResult

Invoke-BpaModel                            Invoke-BpaModel

Set-BpaResult                              Set-BpaResult

With the BestPractices module, it is rather easy to see how many commands it exports. But with a module such as the ActiveDirectory module, it may not be quite so easy. I could pipe the results to the Measure-Object cmdlet—but because the ExportedCommandsproperty contains a dictionary object, it means I have access to the Countproperty. Therefore, I can simply add Countto the end of the command and arrive at the number of commands that are exported by the module. This technique is shown here.

PS C:\> (Get-Module bestpractices).exportedcommands.count

4

OK, that is cool, but what I really need is the ability to obtain the module name and the number of commands it exports. To do this, I need to create a custom object. The easiest way to create a custom object is to use the Select-Object cmdlet and select the properties I need. While I am at it, I want to create a custom label. The following is the command that I arrive at.

PS C:\> Get-Module bestpractices | select name, @{LABEL='cmdletCount';EXPRESSION={$_.exportedcommands.count}}

Name                                                                     cmdletCount

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

BestPractices                                                                      4

Cool. I can now simply delete the BestPracticesmodule name, and I will obtain a list of all modules and the number of commands they export. Here is the revised code:

Get-Module | select name, @{LABEL='cmdletCount';EXPRESSION={$_.exportedcommands.count}}

This works great. But one problem is that the output is not in order. To do this, I simply add Sort-Object at the end of the command. (One nice thing about creating a custom object as output is that I can use Windows PowerShell to further manipulate the output.) The following command is a single-line command that I have broken for readability on the blog.

Get-Module |

select name, @{LABEL='cmdletCount';EXPRESSION={$_.exportedcommands.count}} |

sort cmdletcount –Descending

The command and the output associated with the command are shown here.

Image of command output

I can even pipe the results to the Out-GridView cmdlet and have a graphical tool to filter my results. This is shown in the following code.

Get-Module |

select name, @{LABEL='cmdletCount';EXPRESSION={[int]$_.exportedcommands.count}} |

sort cmdletcount -Descending |

Out-GridView

The Out-GridView tool is shown here.

Image of menu

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 Disabled Features in Windows 8

0
0

Summary: Use Windows PowerShell to find disabled Windows features in Windows 8.

Hey, Scripting Guy! Question How can I use Windows PowerShell 3.) in Windows 8 to find disabled Windows features?

Hey, Scripting Guy! Answer Use the Get-WindowsOptionalFeature cmdlet with the –online parameter and filter for a state of disabled:

Get-WindowsOptionalFeature -Online | ? state -EQ 'disabled'

 

Understanding PowerShell and Basic String Formatting

0
0

Summary: Microsoft Scripting Guy, Ed Wilson, talks about understanding Windows PowerShell and basic string formatting.

 Hey, Scripting Guy! QuestionHey, Scripting Guy! I am really confused. It seems that at times you pull off some really wild string formatting, and I have yet to see it documented very well. I have your new Windows PowerShell 3.0 Step by Step book on order, but it has not yet arrived, so I do not know if you talk about this there. Even if you do, I would like you to help me out with this because it looks really powerful—but it also seems nearly impossible to understand.

—VT

Hey, Scripting Guy! Answer Hello VT,

Microsoft Scripting Guy, Ed Wilson, is here. This morning my day started with an early visit to the dentist. Although my dentist is nice, the worst thing about my visit was when I was leaving she said, “No tea for at least six hours.” Major bummer.

Intro to Windows PowerShell composite formatting

Windows PowerShell provides access to the .NET Framework composite formatting feature. Composite formatting takes a list of objects and a composite formatting string as input. These consist of indexed place holders that are called format items. The output is a string that consists of the original text intermixed with the string representations of the objects in the list.

Composite formatting methods

Several methods support the composite formatting feature, and there are many different formatting types available.

Note   For reference information about this technique, see Composite Formatting on MSDN.

Example 1: Use static Format method

The System.String .NET Framework class has a Formatstatic method that accepts composite formatting techniques. The following illustrates using this technique.

PS C:\> [string]$name = 'Scripting Guy'

PS C:\> [string]::Format("Name = {0}",$name)

Name = Scripting Guy

Example 2: Use the Format operator

By using the -f Windows PowerShell format operator, I can accomplish the same thing. This is shown here.

PS C:\> [string]$name = 'Scripting Guy'

PS C:\> "Name = {0}" -f $name

Name = Scripting Guy

Example 3: Use an Expanding string

Of course, I do not have to use composite formatting, because with Windows PowerShell I can use an expanding string, to accomplish the same thing. This is shown here.

PS C:\> [string]$name = 'Scripting Guy'

PS C:\> "Name = $name"

Name = Scripting Guy

Understanding the three string techniques

In the previous three examples, the outcome is exactly the same—the string “Name = Scripting Guy” returns from the command. So which one is best to use? From an understandability perspective, I think the Windows PowerShell format operator syntax (example 2) is the least intuitive, and next is the Formatstatic method (example 1). The most understandable is the expanding string (example 3).

But even the expanding string is not exactly intuitive because it is unexpected behavior, and it can be confused with non-expanding strings (that use single quotation marks). In more complex examples, using an expanding string becomes very hard to read, and it can be error prone. So for something simple like substituting a name in a string for something supplied via a variable, it is fine. But for more complex string formatting, I use composite formatting. So I want to talk about that a bit more.

How does composite formatting work?

Example 1 and example 2 use composite formatting. The format item is “{0}”, and it has an index of 0. This index component is mandatory, and it is sometimes called a parameter specifier (I often use this term). Note that the index always begins with a number starting from 0 and it corresponds to the items in the list of objects. Therefore, an item using parameter specifier 0 corresponds to the first object in the list of objects. In examples 1 and 2, the object list is simply the variable $name. It is possible to use multiple format items. Examples 4, 5, and 6 illustrate this technique.

Example 4: Use the static Format method with two format items

In this example, I assign strings to the variables $name and $statement. In the formatted output, I want to use the static strings The and thinks that in addition to the exclamation point ! in the output. I also substitute values stored in the two variables. The only thing that is a bit confusing is the multiple commas that appear in the method signature.

PS C:\> [string]$name = 'Scripting Guy'

PS C:\> [string]$statement = 'PowerShell rocks'

PS C:\> [string]::Format("The {0} thinks that {1}!",$name,$statement)

The Scripting Guy thinks that PowerShell rocks!

Example 5: Use the Format operator and two format items

After you figure out how to read the Windows PowerShell Formatoperator, it is easier to use. This is because when you learn to look for the list of objects on the right side of the –f and the composite formatting string on the left side of the –f operator, it becomes easy to read and understand. It is actually easier that reading the complex method call used by the Formatstatic string method.

PS C:\> [string]$name = 'Scripting Guy'

PS C:\> [string]$statement = 'PowerShell rocks'

PS C:\> "The {0} thinks that {1}!" -f $name, $statement

The Scripting Guy thinks that PowerShell rocks!

Example 6: Use an expanding string with two format items

Using an expanding string with two format items becomes a bit more complicated to read. This is because the variables and the static string items merge, such as $statement! I was not certain this would work properly until I tried it (it could have required escaping).

PS C:\> [string]$name = 'Scripting Guy'

PS C:\> [string]$statement = 'PowerShell rocks'

PS C:\> "The $name thinks that $statement!"

The Scripting Guy thinks that PowerShell rocks!

VT, that is all there is to start using compositing formatting. Formatting Week will continue tomorrow when I will talk about some of the advanced uses of composite formatting. There is some really cool stuff coming up tomorrow, and you will not want to miss it.

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: Display the Date in Month, Day, Year Format

0
0

Summary: Learn how to use Windows PowerShell to display the date in a month, day, and two-digit year format.

Hey, Scripting Guy! Question How can I use Windows PowerShell to display the date in a month, day, and two-digit number format with a hyphen between each of the elements?

Hey, Scripting Guy! Answer Use the ToString method from the Get-Date cmdlet and specify a pattern to achieve your desired results:

PS C:\> (get-date).ToString("MM-dd-yy")

03-11-13


Use PowerShell to Format Strings with Composite Formatting

0
0

Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to specify composite formatting to format strings.

Hey, Scripting Guy! Question Hey, Scripting Guy! Often I need to create an output string that is the result of multiple computations. In the past, I have used multiple lines to create this sort of outputs, but now I would like to simplify the process. Do you have any suggestions?

—DB

Hey, Scripting Guy! Answer Hello DB,

Microsoft Scripting Guy, Ed Wilson, is here. Ah, now I can enjoy a nice cup of tea. I am sipping a cup of Lapsang Sochong tea. I generally add milk to the tea and use a bit of honey with it. To me the milk and honey mix well with the smoky flavor of the tea.

Note   This is the second blog post in a series of five that talk about using format methods and operators in Windows PowerShell. The first blog, Understanding PowerShell and Basic String Formatting, provided a great overview to the basics of using the Formatmethod from the String class and the Format operator from Windows PowerShell for composite formatting.

Formatting objects in strings

The first thing I want to talk about today is using format specifiers to control the way that certain objects display. The format item syntax of this technique is shown here:

{index:formatString}

Note   For reference information about this technique, see Composite Formatting on MSDN.

Using format strings with composite formatting

Many of the format specifiers are usable directly within the format item. The following examples illustrate using this technique. The first example illustrates using the WriteLinestatic method from the System.Console .NET Framework class. The second method illustrates performing the same task by using the format operator from Windows PowerShell, and the last example illustrates using the Formatstatic method from the System.String .NET Framework class. The Windows PowerShell format operator and the Formatstatic method were illustrated in yesterday’s Hey, Scripting Guy! Blog, Understanding PowerShell and Basic String Formatting.

Example 1: Use format string with the WriteLine static method

The WriteLinestatic method from the System.Console .NET Framework class writes directly to the Windows PowerShell console. It does not send objects down the pipeline. This behavior is the same as using the Write-Host cmdlet. The command shown here uses a format item that that specifies the index of 0 for the first item, and a format string of C. The Cformat string is a Standard Numeric Format String, and it is the Currency Format Specifier. The object supplied to the format item is the number 100. Following is the code and the output associated with the code.

PS C:\> [console]::writeline("The price is {0:C}", 100)

The price is $100.00

Example 2: Use format string with the Windows PowerShell format (-f) operator

The format operator, -f, places the composite formatting with the format item on the left side of the -f operator and the object list on the right side of the -f operator. The format item uses the same format string, and the same value supplies the format item. Following is the code and the output associated with the code.

PS C:\> "The price is {0:C}" -f 100

The price is $100.00

Example 3: Use the format string with the Formatstatic method

The Format static method from the string class works exactly the same as the WriteLinemethod from the System.Console .NET Framework class with one important exception: It returns a string. It will send a string down the Windows PowerShell pipeline. Other than that, the format item is the same, and the output appears the same. The command and the output associated with the code are shown here.

PS C:\> [string]::Format("The price is {0:C}",100)

The price is $100.00

Using the alignment component

To provide for the formatting of output within “cells,” I use the alignment component of the format item. The alignment component is optional, as seen in the three earlier examples that did not include the alignment component. The alignment is a signed integer that specifies the preferred field width. If the value of the alignment is smaller than the actual length of the formatted string, the value of the alignment component is ignored. Alignment to the right takes place if the value of the integer is positive. Alignment to the left takes place if the integer is negative. The following examples illustrate various ways of using the alignment component.

Example 4: Align a date with a string

Here I store a string in a variable. Next I call the WriteLinestatic method from the System.Console .NET Framework class. The format item substitutes the first object (the $attendee variable value) at the beginning of the output string. Next I use a string literal (attended), and I use the standard Windows PowerShell “carriage return and line feed” (`r`n) characters to move the output to the second line. Now I specify the second substitution object, which is the result of using the Get-Date cmdlet (turning it into a string) and using the d. The d standard format specifier represents a custom date time format that is culture specific. It provides a short date pattern in the pattern that is defined by the current culture settings.

In the second format item, after specifying the second object, a positive 18 appears. This is shown here.

 {1,18}

The  positive 18 means to space over 18 spaces from the left. This code and its associated output are shown here.

PS C:\> $attendee = "Ed Wilson"

PS C:\> [console]::Writeline("{0} attended `r`n{1,18}", $attendee, (Get-Date).tostring('d'))

Ed Wilson attended

          3/7/2013

Example 5: Short way to align a date with string

In this example I do basically the same thing as I accomplished in Example 4. So I am not going to repeat everything from that example. The big difference here is in the second format item. I use a third position to specify the dshort date format specifier. This permits greater simplicity of the code that I used in Example 4. By using this third position, I am able to tell the object returned by Get-Date to display in short date format. Therefore, I avoid the ToStringmethod call and using the d short date specifier there. As shown here, the output is the same—the only change is in the second format item and the call for the second object (highlighted in red).

[console]::Writeline("{0} attended `r`n{1,18:d}", $attendee, (Get-Date))

PS C:\> $attendee = "Ed Wilson"

PS C:\> [console]::Writeline("{0} attended `r`n{1,18:d}", $attendee, (Get-Date))

Ed Wilson attended

          3/7/2013

DB, that is all there is to using composite formatting and specifying additional parameters. Formatting Week will continue tomorrow when I will talk about formatting numbers.

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 a Sortable Date with PowerShell

0
0

Summary: Use Windows PowerShell to easily create a sortable date.

Hey, Scripting Guy! Question How can I use Windows PowerShell to create an ISO 8601 standard sortable date time-stamp for my logging solution?

Hey, Scripting Guy! Answer Use the Sortable Format Specifier in the ToString method from Get-Date:

PS C:\> (Get-Date).ToString("s")

2013-03-12T13:39:18 

Use PowerShell and Conditional Formatting to Format Numbers

0
0

Summary: Microsoft Scripting Guy, Ed Wilson, shows how to use Windows PowerShell and conditional formatting to format numbers.

Hey, Scripting Guy! Question Hey, Scripting Guy! One of the big problems I have when it comes to using Windows PowerShell is figuring out how to properly format numbers. I mean, I can easily use [int] to get rid of hundreds of decimal places, but it is the other things that cause me fits. Help!

—MI

Hey, Scripting Guy! Answer Hello MI,

Microsoft Scripting Guy, Ed Wilson, is here. I just got off of the phone with the TechEd group. We were discussing plans for the Scripting Guys booth at TechEd in New Orleans, LA. Yes, that is right. If you have not heard, TechEd 2013 is in New Orleans this year. It runs from June 3 – June 6, 2013, and right now, there is a $300.00 discount on the price.

Image of TechEd logo 

Note   This is the third blog post in a series of five that talk about using format methods and operators in Windows PowerShell. The first blog, Understanding PowerShell and Basic String Formatting, provided a great overview to the basics of using the Format method from the String class and the Format operator from Windows PowerShell for composite formatting. The second blog, Use PowerShell to Format Strings with Composite Formatting, dove deeply into the use of composite formatting and using various format specifiers.

Understanding number format specifiers

There are many times when I need to format numbers in various ways. Luckily, I do not have to reinvent the wheel when it comes to consistent number formatting. I can use the standard numeric format specifiers, which are documented on MSDN. By using these format specifiers, I can easily display a number as one of the following.

  Currency “C”

  Decimal “D”

  Exponential “E” 

  Fixed-Point “F”

  General “G”

  Number “N”

  Percent “P”

  Hexadecimal “H”

Note  For reference information about this technique, see Composite Formatting on MSDN. For detailed information about standard format specifiers, see Standard Numeric Format Strings.

Formatting percentages by using a format specifier

When converting a number into a percentage the process usually involves multiplying the number by 100 and displaying a percentage sign.

Note  For a good example of this, using the standard number “N” format specifier, see Weekend Scripter: The Scripting Wife Talks about the First Warm-Up Event in the Winter Scripting Games.

Suppose in my calculations I arrive at the number 5/21, and I want to express it as a percentage. If I use normal formatting, I would need to use a formula such as the following.

PS C:\> (5/21)*100

23.8095238095238

The problem is that I have a LOT of decimal places. I can use the Scripting Wife’s technique to get down to two places by using the “F” format specifier as shown here:

PS C:\> "{0:N2}" -f ((5/21)*100)

23.81

This technique works great, but by using the “P” Percent standard numeric format specifier, I can shorten the amount of work a bit.

Example 1: Write percentage to console

In this example, I store the result of 5/21 into a variable I call $percent. If I look at the value stored in the $percent variable, I see the following:

PS C:\> $Percent

0.238095238095238

To display the value as a percentage, I do not need to multiple by 100 and use techniques to return two decimal places. Instead, all I need to do is use composite formatting. In the format item, I first specify an index number for the object substitution, and then I use a format string to specify that I want to display the output as a percentage. When I do this, the “P” format specifier multiplies the output by 100 and by default displays two decimal places. This is a REAL time saver! The following code illustrates this technique.

PS C:\> $Percent = 5/21

PS C:\> [console]::WriteLine("{0:P}",$percent)

23.81 %

Example 2: Using an overload for the ToString method

In Windows PowerShell, everything is an object—even numbers. This means that an ordinary integerstill has methods and properties. One of the more useful (at least for me) methods is the ToStringmethod. In fact, I use this method from time-to-time when I want to do things such as write numeric values to the registry. One of the really cool features of the ToStringmethod is that is has an overload that permits me to use a format specifier.

Example 2A: Store value in a variable and call a method

In Example 2A, I perform my calculation and store the results in the $percent variable. I use that variable inside the WriteLinemethod, and I call the ToStringmethod and specify that I want to use format specifier “P.” The advantage of this methodology is that it permits you to avoid using conditional formatting by calling the overload of the ToStringmethod.

PS C:\> $Percent = 5/21

PS C:\> [console]::WriteLine(($percent).ToString("P"))

23.81 %

Example 2B: Compute a value inside a method call

In Example 2B, I perform the computation directly inside the method call. The advantage is that this creates a one-line command that is not dependent on an external variable.

PS C:\> [console]::WriteLine((5/21).ToString("P"))

23.81 %

Example 3: Use the Windows PowerShell Format operator

The most concise methodology of using the “P” format specifier to display your output as a percentage is to use the Windows PowerShell Format operator (-f). As I said yesterday, when you get the hang of reading it, it is the shortest way to do your formatting. Following are two examples of using the Windows PowerShell format operator.

Example 3A: Store results in a variable and call with the operator

In Example 3A, I store the results of my computation in a variable that I call $percent. I then use conditional formatting, and in my format item, I specify the first index value (0) to display as a percentage. The “P” format specifier goes in the second half of the format item. On the other side of the –f Windows PowerShell format operator, I use the $percent variable to pass my object to the format item. Here is the script.

PS C:\> $Percent = 5/21

PS C:\> "{0:P}" -f $Percent

23.81 %

Example 3B: Use the computation directly

In Example 3B, I do not need to use an intermediate variable. I can use conditional formatting directly as shown here.

PS C:\> "{0:P}" -f (5/21)

23.81 %

Example 4: Specify more than (or less than) two decimal places

In my format item (the “{0:P}” part of the conditional formatting string), I can specify precision on the right side of the “P” format specifier. In this way, I can display a percentage as three decimal places, one decimal place, or whatever value is appropriate. This technique is shown here.

PS C:\> "{0:P3}" -f (5/21)

23.810 %

Example 5: Compute percentages with admin constants

The admin constants (KB, MB, GB) make it easy to work with data that is returned from my computer. For example, the following command returns basic process information about the Explorer process on my computer.

PS C:\> Get-Process explorer

 

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName

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

   1818      96    47684     113708   623    18.21   1328 explorer

OK, so the process is using 623 megabytes of virtual memory. Is this good or bad? I need to compare it to total system memory, which on my new laptop is 16 gigabytes. Dude, I do not want to mess with all that math. No problem. The “P” format specifier can handle it. Here are the results.

PS C:\> "{0:P}" -f (623MB/16GB)

3.80 %

Revisiting the Scripting Wife’s solution

The real power of using conditional formatting, format specifiers, format items, and the like is that I can incorporate it with my other Windows PowerShell “tricks” to arrive at really powerful and useful solutions.

The Scripting Wife came up with a great one-liner to show the percentage of disk utilization on her system. In her solution, she used a number of great Windows PowerShell tricks including conditional formatting. (I do not think she knew that is what she was doing, but she did find a great example to adapt to her needs).

She also used a great trick with the Select-Object cmdlet where she created a custom property on the outputted object. This is powerful stuff. So the only thing I am going to do is steal her code, and modify it to use the “P” format specifier instead of using the “N” format specifier.

gwmi win32_volume |

ft DriveLetter, FreeSpace, Capacity,

@{Label="PercentFree";Expression= {"{0:P}" -f ($_.freespace / $_.capacity)}}

MI, that is all there is to using Windows PowerShell to format numbers by using conditional formatting. Formatting Week will continue tomorrow when I will talk about formatting dates. It is fun. It is powerful. And you really, really do not want to miss it. See you then.

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: Display the Value of Pi to Three Decimal Places

0
0

Summary: Use Windows PowerShell to display the value of Pi to three decimal places.

Hey, Scripting Guy! Question How can I display the value of Pi to three decimal places by using conditional formatting to avoid rounding numbers up or down?

Hey, Scripting Guy! Answer Use the Fixed-Point (“F”) Format Specifier, and specify the number of desired decimal places. The following technique uses the Windows PowerShell format operator.

PS C:\> "{0:F3}" -f [math]::PI

3.142

 

Use PowerShell and Conditional Formatting to Format Dates

0
0

Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell and conditional formatting to control the format of dates.

Hey, Scripting Guy! Question Hey, Scripting Guy! I know that Windows PowerShell has made it easier to deal with dates, especially with some of the tricks that are available via the Get-Date cmdlet. But at times I need to display different types of dates, and I end up doing old-fashioned string manipulation like I did back in the 70s. Now don’t get me wrong, I loved the 70s with the groovy music, polyester shirts, leisure suits, and big hair, but string manipulation was not part of that groovy scene.

—CG

Hey, Scripting Guy! Answer Hello CG,

Microsoft Scripting Guy, Ed Wilson, is here. CG, thanks for the flashback! I just wonder if Microsoft PowerShell MVP, Sean Kearney, is thinking about spoofing Stayin’ Alive. Maybe something like, “Hey, hey, hey, scriptin’ it live”?

It is another beautiful day here in Charlotte, North Carolina. On Facebook, we are constantly seeing pictures of large piles of snow and the like, but we have not had more than a dusting here all winter. For us, it seems that winter is over, and spring is already knocking at the door. Some of our more obsessive neighbors have already pulled out their lawn mowers and are trying to make the rest of us look bad. Oh well. I am sitting here sipping a nice cup of Gunpowder green tea, with a bit of jasmine, crushed cinnamon stick, juniper berries, lemon grass, and a pinch of spearmint. It is wonderfully refreshing.

Note   This is the fourth blog post in a series of five that talk about using format methods and operators in Windows PowerShell.

Understanding standard date and time format specifiers

The cool thing about using standard date and time format specifiers to format dates is that I do not need to worry if my script runs on another computer that may have a different culture format. By default, when I use a date and time format specifier, it automatically uses the culture of my local computer. In this way, the date and time information always displays correctly on whatever computer the script runs.

Note   For complete documentation about these specifiers, see Standard Date and Time Format Stringson MDSN.

Use the Format parameter for Get-Date

The easiest way to use the standard date and time format specifiers is to use the –formatparameter from the Get-Date cmdlet. For example, if I need the date in a short form, such as 3/11/2013 (the month/day/year format that we commonly express in the United States), I use the “d” pattern. The “d” pattern is the short date pattern. This technique is shown here.

PS C:\> Get-Date -Format d

3/11/2013

Note   The format specifiers are ALWAYS case sensitive. There are a few occasions when the format specifier appears as “M”, “m”. This means that I can use the upper case or the lower case “m”. In the case of “d”, the “d” format specifier is the short date pattern and “D” is the long date pattern. This pattern of short equals lower case and long equals upper case is commonly used. For example, “t” is the short time pattern and “T” is the long time pattern.

The following image illustrates the use of the standard date and time format specifiers with the Get-Date cmdlet.

Image of command output

Formatting strings

One thing to keep in mind is that when I specify a format for the output from Get-Date, I have converted my System.DateTime object to a string. At this point, I can no longer perform any date and time computations or conversions. These are strictly formatted output techniques. This does not mean that I cannot send the output to an Excel spreadsheet or a SQL Server database for further processing, but it is no longer a DateTime object.

In addition to specifying the format via Get-Date, I can also specify it via techniques that use conditional formatting. The following examples illustrate a few ways to accomplish this requirement.

Example 1: Use the Formatmethod from the String class

In Example 1, I use the static Formatmethod from the System.String .NET Framework class. In the Format item, I add in the first index, 0, which will populate via the Get-Date cmdlet. The format string is “R”, which creates an RFC1123 pattern.

PS C:\> [String]::Format("{0:R}",(get-date))

Mon, 11 Mar 2013 14:37:03 GMT

Example 2: Use the PowerShell format operator

I can use the Windows PowerShell Format (-f) operator to format the way the date displays information. On the left side of the –f operator, I place my format item with the applicable format specifier. On the right side of the –f operator, I call Get-Date. In the following technique, I use the Universal full date/time pattern.

PS C:\> "{0:U}" -f (Get-Date)

Monday, March 11, 2013 6:38:10 PM

Example 3: Show date in a specific culture

It is possible to create culture settings to permit displaying a date in a different format. The easiest way to do this is to use the New-Object cmdlet and create an instance of the Globalization.CultureInfo .NET Framework class. When I do this, I must specify the culture that I want to create. I can find the names of the cultures to create by referring to the National Language Support (NLS) API Reference.

Therefore, all I need to do after I create the new instance of the CultureInfo class is specify the style to display the date and specify the culture. In the following example, I get the current date and store it in a variable named $date. Next, I create the culture information for culture de-DE (German Germany) by using the New-Object cmdlet and specifying the culture name “de-DE”. Next, I use the WriteLinemethod to display the date as a string. I use the “D” format specifier to display a long date. Next, I specify the culture that I stored in the $ci variable. The output shows in German.

PS C:\> $date = get-date

PS C:\> $ci = New-Object globalization.cultureinfo("de-DE")

PS C:\> [console]::writeline($date.ToString("D",$ci))

Montag, 11. März 2013

However, when I use the Get-Culture cmdlet, I show that my current culture setting is English (United States).

PS C:\> Get-Culture

 

LCID             Name             DisplayName

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

1033             en-US            English (United States)

Note  For excellent information about using culture settings to format dates, see the Hey, Scripting Guy! Blog, Use Culture Information in PowerShell to Format Dates.

CG, that is all there is to using Windows PowerShell to format dates. Format Week continues tomorrow when I will talk about using Windows PowerShell to format time spans.

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 UNIX Date Formatting in PowerShell

0
0

Summary:  Learn how to use UNIX date formatting in Windows PowerShell.

Hey, Scripting Guy! Question How can I use my prior knowledge of UNIX date formatting to specify dates in Windows PowerShell?

Hey, Scripting Guy! AnswerUse the Get-Date cmdlet and the –Uformat parameter. For example, to display a date in standard format for your current locale, use the “x” format specifier:

PS C:\> Get-Date -UFormat %x

03/11/13 

Use PowerShell and Conditional Formatting to Format Time Spans

0
0

Summary: Learn how to use Windows PowerShell and conditional formatting to discover and  format time spans.

Hey, Scripting Guy! Question Hey, Scripting Guy! What is a time span, and why would I want to use one? Just sayin'…

—JR

Hey, Scripting Guy! Answer Hello JR,

Microsoft Scripting Guy, Ed Wilson, is here. This morning is one of those mornings that remind me of when I was growing up in Florida. The sky is overcast, and a ground fog clothes the lawn. The air is cool, but heavy with humidity. I am positive I hear sea gull calls pierce the thick silence, yet I have not seen a sea gull in months. Maybe I am not certain that I am in Charlotte, North Carolina after all. I am sipping a cup of Darjeeling tea with cinnamon stick, lemon grass, peppermint, spearmint, licorice root, and juniper berries, and munching on a freshly baked strawberry scone while I check my scripter@microsoft.com email.

JR, a time span measures the amount of time that is elapsing from one point in time to another point in time. Therefore, when figuring out the amount of time between March 14, 2013 and March 12, 2013, a TimeSpan object returns as shown here.

PS C:\> [datetime]"3/14/13" -[datetime]"3/12/13"

 

Days              : 2

Hours             : 0

Minutes           : 0

Seconds           : 0

Milliseconds      : 0

Ticks             : 1728000000000

TotalDays         : 2

TotalHours        : 48

TotalMinutes      : 2880

TotalSeconds      : 172800

TotalMilliseconds : 172800000

Note   This is the last blog post in a series of five that talk about using format methods and operators in Windows PowerShell.

The problem with the default display of a TimeSpan object

By default, Windows PowerShell displays all of the properties associated with a TimeSpan object. As seen in the previous script, the output can be a bit cluttered. This is OK if I am working interactively from within the Windows PowerShell console and I only want to see something like the amount of time that has lapsed between two dates.

I can see the different properties when I send the TimeSpan object to the Get-Member cmdlet. This technique is shown here.

[datetime]"3/14/13" -[datetime]"3/12/13" | Get-Member -MemberType *property

The command and the output associated with the command are shown in the following image.

Image of command output

So, if I only want to know the number of hours between two date/time objects, I need to first find out the property name (by using Get-Member or by simply running the command and examining the output). Then I can use the group and dot method to retrieve the specific property. This is shown here.

PS C:\> ([datetime]"3/14/13" -[datetime]"3/12/13").totalhours

48

In general, I use this technique when I am interested in a specific property from a TimeSpan object. But there is a better (and much more flexible) way to obtain exactly what I want from a TimeSpan object.

Use composite formatting and standard TimeSpan format strings

The easiest way to use the standard TimeSpan format strings is to combine them with composite formatting. When I do this, it provides three formats. The formats are shown in the following table.

Format Specifier

Name

  “c”

  Constant format (not culture sensitive.

  [-]d.hh:mm:ss.[fffffff]

  “g”

  General short format (culture sensitive)

  [-]d.hh:mm:ss.[fffffff]

  “G”

  General long format (culture sensitive)

  [-]d.:hh:mm:ss.fffffff

Note   For complete documentation about these specifiers, see Standard TimeSpan Format Stringson MDSN.

An example of using the three standard TimeSpan format strings with composite formatting is shown in the image that follows.

Image of command output

Note   For complete information about composite formatting, see Composite Formatting on MSDN.

Example 1: Use the static WriteLinemethod

To use standard TimeSpan format strings with the static WriteLinemethod from the system.console .NET Framework class, I use a string to identify the value I display, and then I use a format item with the “c” format specifier. The “c” format specifier is a constant value that is not cultural sensitive. Therefore, the values always appear in the same order. The second parameter that the WriteLinemethod accepts is a TimeSpan object. The script and its associated output are shown here.

PS C:\> $ts = [datetime]"3/14/13" -[datetime]"3/12/13"

PS C:\> [console]::WriteLine("The lapsed time is: {0:c}", $ts)

The lapsed time is: 2.00:00:00

Example 2: Use the Windows PowerShell format operator

To use standard TimeSpan format strings with the Windows PowerShell format operator, I add a string descriptor, and then use my format item to specify the substitution object and the format to use on the left side of the format operator. On the right side of the format operator, I specify the variable holding the TimeSpan object. The script is shown here.

PS C:\> $ts = [datetime]"3/14/13" -[datetime]"3/12/13"

PS C:\> "The lapsed time is: {0:g}" -f $ts

The lapsed time is: 2:0:00:00

Example 3: Time span with milliseconds

One of the things that is useful with the “c” and the “g” standard TimeSpan format strings is that they display the portion of the TimeSpan object that is required. Therefore, if a time span does not span days, it omits the days portion. If a TimeSpan object populates milliseconds, it adds that portion of the object.

In the script that follows, I store the current DateTime object. I wait for a while, and then I store a second DateTime object. Now I create a TimeSpan object representing the difference between the two TimeSpan objects. Lastly, I use the Windows PowerShell format operator to display a culture sensitive short time span. Because both times occurred on the same day, the day portion of the object does not display.

PS C:\> $now = get-date

PS C:\> $later = get-date

PS C:\> $nts = New-TimeSpan -Start $now -End $later

PS C:\> "The timespan is {0:g}" -f $nts

The time span is 0:09:03.1051821

This technique is shown here, and it illustrates the difference between the three standard time span format strings.

Image of command output

JR, that is all there is to using a time span. Join me tomorrow for the Weekend Scripter when I will talk about using a custom time span format specifier.

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 the Number of Seconds in Three Days

0
0

Summary: Use Windows PowerShell to easily find the number of seconds in three days.

Hey, Scripting Guy! Question How can I use Windows PowerShell to find how many seconds are in three days without diving into a bunch of multiplication or division?

Hey, Scripting Guy! Answer Use the New-TimeSpan cmdlet to create a time span of three days, and select the TotalSeconds property:

PS C:\> (New-TimeSpan -Days 3).totalseconds

259200 

Weekend Scripter: Use PowerShell and Custom Time Span Format Strings

0
0

Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell and custom time span format strings to display lapsed time.

Microsoft Scripting Guy, Ed Wilson, is here. This morning I am awake and sipping a nice cup of English Breakfast tea with a little peppermint and spearmint leaves in it. I am thinking back over yesterday’s Hey, Scripting Guy! Blog post about Use PowerShell and Conditional Formatting to Format Time Spans, and I am a bit unhappy—oh, not about the blog—I thought it was pretty cool. I am unhappy about the limitation of the Standard Timespan Format Strings. They just are not that flexible.

Note   This is the last blog post in a series of five that talk about using format methods and operators in Windows PowerShell.

So anyway, I thought I would take a look at creating a custom time span format string so I could display only the information I needed.

Note   For complete documentation about these specifiers, see Standard TimeSpan Format Stringson MDSN. For complete information about composite formatting, see Composite Formatting

Custom TimeSpan format strings

There is a great big table on MSDN that describes the custom TimeSpan format strings. For me, however, I only need to remember four. The four I like to use are shown in the following table.

Format Specifier

Description

  “dd”  

  Number of whole days in the time interval. Uses a leading zero as required.

  “hh”

  Number of whole hours in the time interval (not including those that make up complete days). Therefore, an interval of 25 hours would report 01. To see the days, you would need to also use “dd”.

  “mm”

  Number of whole minutes in the time interval (not including those that make up complete hours). Therefore, an interval of 65 hours would report 05. To see the hours, you would need to also use “hh”.

  “ss”

  Number of whole seconds in the time interval (not including those that make up complete minutes). Therefore, an interval of 65 seconds would report 05. To see the minutes, you would need to also use “mm”.

If I use a format specifier that is a single letter, such as “d”, I get the number of days without a leading zero. That, for me, makes sense; and therefore I do not need to remember four additional format specifiers—I simply know that they exist. The following script illustrates using a custom TimeSpan format string to display only the days that exist between two dates in a TimeSpan object. The nice thing about this technique is that I can design my output exactly in the way I wish, and then by using the format specifier.

PS C:\> $ts = [datetime]"3/14/13" -[datetime]"3/12/13"

PS C:\> "The lapsed time is: {0:dd} days" -f $ts

The lapsed time is: 02 days

Reusing the input object

One of the things that makes this technique so powerful is the ability to easily pull out the exact pieces from the TimeSpan object that I need to use in my output. It is much easier that using subexpressions to attempt to expand properties from the object. When I know how to use the appropriate format specifiers in the format item, I construct my string, and I select what I need to see. This makes for a much easier way of reading the time span than either the short or long time span formats that I presented in Use PowerShell and Conditional Formatting to Format Time Spans.

PS C:\> "The lapsed time is: {0:dd} days and {0:hh} hours" -f $ts

The lapsed time is: 02 days and 00 hours

I can continue to reuse the object and display days, hours, minutes, seconds, and even milliseconds if I need them. (Although in such a situation, I probably would go back and use the long format specifier “G” from the standard TimeSpan format strings. The following example illustrates the technique of picking out days, hours, and minutes from the TimeSpan object.

PS C:\> "The lapsed time is: {0:dd} days and {0:hh} hours and {0:mm} minutes" -f $ts

The lapsed time is: 02 days and 00 hours and 00 minutes

The previous script and its associated output are shown in the image that follows.

Image of command output

That is about it for today, and my tea is getting cold. Join me tomorrow when I will talk about using Windows PowerShell to configure a new laptop. It is a cool blog, and I’m sure you will enjoy it.

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 in to Find Running Tasks

0
0

Summary: Learn how to use Windows PowerShell in Windows 8 or Windows Server 2012 to find running scheduled tasks.

Hey, Scripting Guy! Question How can I use Windows PowerShell 3.0 in Windows 8 or Windows Server 2012 to find running scheduled tasks?

Hey, Scripting Guy! AnswerUse the Get-ScheduledTask cmdlet and filter out the state that is equal to running. In the following example, ? is an alias for the Where-Object.

Get-ScheduledTask | select taskname, state | ? state -eq 'running' 

Weekend Scripter: Use PowerShell to Configure a New Laptop

0
0

Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to configure a new laptop.

Microsoft Scripting Guy, Ed Wilson, is here. WooHoo! My new laptop arrived. Oh, no…I now have a lot of work to do to install and configure Windows 8 on it. You see, I never, never simply turn on and use a new laptop—that is not the way I operate. I always do a fresh installation. I am not saying one needs to always do this, but I like to know what is going on and make my own decisions. So here I am with a lot of work to do.

Setting up the new laptop

A while back I began working on a new computer deployment module that helps me configure a number of things that simply irate me about default installs. Today I am going to discuss a few types of things that I need to configure.

I do not want to defrag my SSD drive

This one is easy. In Windows 8, there is a Scheduled Task module, and all I need to do is disable one scheduled task. When I first tried the command, I received the following error message:

PS C:\> Get-ScheduledTask -TaskName *defrag* | Disable-ScheduledTask

Disable-ScheduledTask : Access is denied.

At line:1 char:40

+ Get-ScheduledTask -TaskName *defrag* | Disable-ScheduledTask

+                                        ~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : PermissionDenied: (PS_ScheduledTask:Root/Microsoft/..

   .S_ScheduledTask) [Disable-ScheduledTask], CimException

    + FullyQualifiedErrorId : HRESULT 0x80070005,Disable-ScheduledTask

When I started Windows PowerShell with Admin rights, the command came off without a hitch as shown here.

PS C:\> Get-ScheduledTask -TaskName *defrag* | Disable-ScheduledTask

 

TaskPath                                       TaskName                          Sta

                                                                                 te

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

\Microsoft\Windows\Defrag\                     ScheduledDefrag                   Dis

I do not want to hibernate

Windows 8 has a cool feature called Fast Start. Unfortunately, I have a scavenged SSD in my laptop that is really small, so I cannot afford the disk space of Hiberfile.sys. Anyway, guess what? Windows 8 on an SSD boots up pretty quickly anyway. So this is a simple one-line command using the PowerCfg command-line tool.

Powercfg /H OFF

Note   This command also requires Admin rights. If you run it without Admin rights, the following error arises:

PS C:\> powercfg /H OFF

An unexpected error condition has occurred. Unable to perform operation. You may not have permission to perform this operation.

I want to manage my own page file

If I use Get-CimInstance to query for instances of Win32_PageFileSetting, guess what? It returns nothing—not a thing. There is not an instance of Win32_PageFileSetting because Windows is managing the page file.

Disable auto management of the page file

So the first thing I need to do is to turn off auto management of the page file. I use the Win32_ComputerSystem WMI class to do this. Here is the command.

PS C:\> Set-CimInstance -Query "Select * from win32_computersystem" -Property @{autom

aticmanagedpagefile="False"}

PS C:\> Get-CimInstance win32_PageFileSetting

 

                 MaximumSize Name                        Caption

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

                           0 C:\pagefile.sys             C:\ 'pagefile.sys'

Specify the size of the page file

To set the size of the page file, I can now use the Set-CimInstance cmdlet, and set the size by using the Win32_PageFileSetting cmdlet. Here is the script I used.

PS C:\> Set-CimInstance -Query "Select * from win32_PageFileSetting" -Property @{Init

ialSize=3072;MaximumSize=3072}

It took a few times before I came up with the right combination. In the end, I looked up the Win32_PageFileSetting WMI class on MSDN, and I found that it wants the values in megabytes.

Image of command output

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 Identify SSD

0
0

Summary: Use Windows PowerShell to find a solid-state drive (SSD).

Hey, Scripting Guy! Question How can I use Windows PowerShell to find computers that have a solid-state drive (SSD)?

Hey, Scripting Guy! Answer In Windows 8, use the Get-Disk function, and search the model information for the letters SSD:

PS C:\> get-disk | ? model -match 'ssd'

 

Number Friendly Name                            OperationalS  Total Size Partition

                                                tatus                    Style

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

0      INTEL SSDSA2BW160G3L                     Online         149.05 GB GPT

Hey, Scripting Guy! Answer In Windows 7 and earlier, use the Get-WmiObject cmdlet and query the Win32_DiskDrive WMI class:

PS C:\> Get-WmiObject win32_diskdrive | where { $_.model -match 'SSD'}

 

Partitions : 3

DeviceID   : \\.\PHYSICALDRIVE0

Model      : INTEL SSDSA2BW160G3L

Size       : 160039272960

Caption    : INTEL SSDSA2BW160G3L 

 

Viewing all 3333 articles
Browse latest View live




Latest Images