In PowerShell, you easily format a string with the help of the -f operator. In this post, I will explain the basics of composite string formatting.

Imagine that you’re on the planning committee for an upcoming tech conference. Because you love PowerShell, you plan to use it to pull attendee data from a SQL Server database and present “pretty” output. In this article, we’re not concerned with the SQL–PowerShell access; instead, we simply want to generate formatted string output.

For example, let’s say that we need to print conference registration dates in a reader-friendly way such as this:

<attendee name> registered for the conference on <date>

Perhaps we also want to print out how much money each attendee invested in his or her registration:

<attendee name> spent a total of <currency>.

Please remember that PowerShell is, well, a powerful shell because it wraps the .NET Framework in an IT pro-friendly package. Thus, we have access to the core .NET Framework string formatting methods. In this article, I’ll show you one way: the –Format operator (usually abbreviated to –f).

Some background information on types ^

All programming languages classify different types of data into types; PowerShell is no different. What’s convenient about PowerShell, though, is that it’s a dynamically typed language. This means that PowerShell “chooses” the appropriate type based on the style of data you present. For instance:

$money = 123.45

How can we tell what type PowerShell assigned to the $money variable? Let’s consult the native GetType() object method:

PS C:\> money.GetType() | Select-Object -Property Name

Name 
---- 
Double

That makes sense. PowerShell sees a decimal value as a Double. You should find that integers such as 123 or 45 return the Int32 type. If we’re doing mathematical operations, then using the numeric data types makes perfect sense. However, we can’t do “pretty print” formatting on numbers; we’ll need to recast the data into string format. Check this out:

PS C:\> $money2 = $money.ToString()

PS C:\> $money2.GetType() | Select-Object –Property Name

Name 
---- 
String

The general best practice with PowerShell scripting is that we do our “heavy lifting” in the body of the script and save our formatting tasks for the end. That’s where string formatting comes in.

Although PowerShell uses dynamic typing, as I said, you can use what are called type accelerators to specify a data type manually:

[string]$strmoney = 321.32

Introducing composite string formatting ^

As I said in the beginning of this article, PowerShell and the underlying .NET Framework give us many ways to format strings. What I’m going to show you now is called composite string formatting using the –f operator.

The word composite here means “made up of various parts or elements.” This means that, in a nutshell, we throw one or more strings at formatting codes that are embedded in our output. You may be thinking, “Tim, what the heck are you talking about?!” Let me explain.

Remember the first output requirement I described? Here it is again in case you have a short memory like I do:

<attendee name> registered for the conference on <date>

Now take a look at the same string, this time with formatting expressions embedded:

$reg = '{0} registered for the conference on {1}'

So our first lesson is that we place ordinal placeholders in our output stream, starting with an index of 0.

Next comes our string data. Let’s whip up a couple variables quickly:

$attendee = 'Tim Warner'
$date = (Get-Date).ToString()

We’ve been using the built-in ToString() method a lot, haven’t we? All that does is convert a non-string data type (such as the current date retrieved with Get-Date) to string format.

This is how you integrate the –f operator with the strings and index placeholders:

$reg = '{0} registered for the conference on {1}' –f $attendee, $date 
$reg

Tim Warner registered for the conference on 5/25/2015 8:16:35 PM

Pretty cool, right? But you’re probably wondering how we can actually add formatting to the output. Let’s do that now.

Adding formatting codes ^

PowerShell/.NET gives us different formatting codes (which are case-sensitive, by the way) depending on the output we need. For example, remember this output requirement:

<attendee name> spent a total of <currency>.

We know how to structure the “skeleton” of the target output string:

$attendee = 'Jay Dickerson'
$date = (Get-Date).ToString('d')
$spent = 2695
$summary = '{0} registered for the conference on {1} and spent a total of {2:C}' –f $attendee, $date, $spent

Usiing composite string formatting with the -f operator

Using composite string formatting with the -f operator

Notice that I snuck the “d” argument in the (Get-Date).ToString() expression. As it happens, d gives you only the date portion of a date/time variable. If you try to put the d in the second index position, such as {1:d}, it won’t work because we’ve already converted the date/time data to a string. I will explain the meaning of “{2:C}” in a minute.

Please consult the Microsoft Developer Network (MSDN) for the full list of date format characters. Here are a few of the more common ones and their meanings:

  • d: short date
  • D: long date
  • f: full date and time
  • m, M: month day pattern

I suggest that you play with these formats, like so:

PS C:\> (Get-Date).ToString('D')
Monday, May 25, 2015

PS C:\> (Get-Date).ToString('f')
Monday, May 25, 2015 8:38 PM

PS C:\> (Get-Date).ToString('M')
May 25

So, the bottom line with composite string formatting is that you use the following general syntax for your “placeholder” expressions:

{indexnumber:formattingcode}

There’s a lot of other stuff you can do in those expressions (such as control alignment and such), but we’ll stick with the raw basics in this tutorial.

Now let’s turn our attention to numbers and currency. In the previous example, you’ve probably put together that C means currency format with the dollar sign and two decimal places; that’s true enough.

Once again, peruse MSDN or TechNet for the full list of number string formatting codes. Here are my favorites:

  • C,c: currency
  • D,d: decimal
  • P,p: percent
  • X,x: hexadecimal
  • G,g: general

Spend time experimenting with these codes, like so:

PS C:\> '{0:p}' -f 0.21
21.00 %
PS C:\> '{0:X}' -f 11
B

Conclusion ^

I hope that this tutorial helps save you time. If your PowerShell experience is anything like mine, massaging your output into the proper format is often just as challenging as adding the main programming logic to your script. Please let us know in the comments what questions, tips, or tricks you have to share with the community.

avatar
12 Comments
  1. Gordon Robertson 3 years ago

    It's one thing to offer a tutorial, which is appreciated, but you should ensure that your examples work when a neophyte tries them verbatim.

    I entered your example $money = 123.45

    PS accepted the value and gave me another prompt. When I entered your next line, money.GetType() | Select-Object -Property Name

    The inline compiler returned an immediate error, indicating it expected and expression after '('. It called it a ParserError.

    I am used to basic programming and I know the slightest syntax error can throw a compiler for a loop. If you knew there should be an expression in the brackets and you have omitted it due to a notion that a reader 'should' know that, then you are writing for the elite of the profession which I don't get.

    How is anyone going to take an interest in Powershell if even the simplest of examples fail to return the answer given by the tutorial writer?

  2. Gordon Robertson 3 years ago

    Timothy...I tried example 2 and it worked. Then I tried example 1 again and got the same error.

    Then I began looking at the money variable. I entered it as written $money = 123.45 but when I entered the 2nd part, I included a '$' before money as in:

    $money.GetType() | Select-Object -Property Name

    and it worked!!! I got:

    Name
    ----
    Double

    You appear to have omitted the $ before money in part 2 of example 1, as in:

    money.GetType(), rather than,
    $money.GetType()

    It never ceases to amaze me how a slight syntax error can prompt a compiler to issue such reprimands, in red print yet.

  3. Gordon Robertson 3 years ago

    Timothy...I am now getting the hang of it and thanks for the tutorial.

    When you format a string using the Date command, Powershell obviously goes to the system clock to retrieve the date and time. Is it possible for Powershell to examine a list and extract dates from it with an associated file name?

    For example, if I have a list of items with accompanying dates in the file list.txt, can I get Powershell to read the list, extract the required information, then produce another list with commands in it to automate a process?

    Essentially, I want to read a text list, extract file info by date, then delete certain files using a command line entry in a Powershell script.

  4. (Sorry for the double post until the first one gets deleted.  Editing the comment stripped out my formatting.)

    Remember - for powershell, the $ indicates it's a variable.  Tim's example just had a typo that you found 🙂

    I don't understand what you are asking here though? Can you give an example of what you are trying to accomplish?

    Now, this may or may not help.. Get-Date just obtains a [DateTime] object from a given set of parameters.  One of the best things about Powershell is discoverability.  You can find out quite a bit of detail from an object using the Get-Member command.  This is typically done with by piping the object into Get-Member, but you can also use the -InputObject to get the same information.  Both of these will produce the same results:

    Get-Date | Get-Member
    Get-Member -InputObject (Get-Date)

    Here is what is outputs:

    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)
    CompareTo Method int CompareTo(System.Object value), int CompareTo(datetime value), int IComparable.CompareTo(System.Object obj...
    Equals Method bool Equals(System.Object value), bool Equals(datetime value), bool IEquatable[datetime].Equals(datetime other)
    GetDateTimeFormats Method string[] GetDateTimeFormats(), string[] GetDateTimeFormats(System.IFormatProvider provider), string[] GetDateT...
    GetHashCode Method int GetHashCode()
    GetObjectData Method void ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serializa...
    GetType Method type GetType()
    GetTypeCode Method System.TypeCode GetTypeCode(), System.TypeCode IConvertible.GetTypeCode()
    IsDaylightSavingTime Method bool IsDaylightSavingTime()
    Subtract Method timespan Subtract(datetime value), datetime Subtract(timespan value)
    ToBinary Method long ToBinary()
    ToBoolean Method bool IConvertible.ToBoolean(System.IFormatProvider provider)
    ToByte Method byte IConvertible.ToByte(System.IFormatProvider provider)
    ToChar Method char IConvertible.ToChar(System.IFormatProvider provider)
    ToDateTime Method datetime IConvertible.ToDateTime(System.IFormatProvider provider)
    ToDecimal Method decimal IConvertible.ToDecimal(System.IFormatProvider provider)
    ToDouble Method double IConvertible.ToDouble(System.IFormatProvider provider)
    ToFileTime Method long ToFileTime()
    ToFileTimeUtc Method long ToFileTimeUtc()
    ToInt16 Method int16 IConvertible.ToInt16(System.IFormatProvider provider)
    ToInt32 Method int IConvertible.ToInt32(System.IFormatProvider provider)
    ToInt64 Method long IConvertible.ToInt64(System.IFormatProvider provider)
    ToLocalTime Method datetime ToLocalTime()
    ToLongDateString Method string ToLongDateString()
    ToLongTimeString Method string ToLongTimeString()
    ToOADate Method double ToOADate()
    ToSByte Method sbyte IConvertible.ToSByte(System.IFormatProvider provider)
    ToShortDateString Method string ToShortDateString()
    ToShortTimeString Method string ToShortTimeString()
    ToSingle Method float IConvertible.ToSingle(System.IFormatProvider provider)
    ToString Method string ToString(), string ToString(string format), string ToString(System.IFormatProvider provider), string To...
    ToType Method System.Object IConvertible.ToType(type conversionType, System.IFormatProvider provider)
    ToUInt16 Method uint16 IConvertible.ToUInt16(System.IFormatProvider provider)
    ToUInt32 Method uint32 IConvertible.ToUInt32(System.IFormatProvider provider)
    ToUInt64 Method uint64 IConvertible.ToUInt64(System.IFormatProvider provider)
    ToUniversalTime Method datetime ToUniversalTime()
    DisplayHint NoteProperty DisplayHintType DisplayHint=DateTime
    Date Property datetime Date {get;}
    Day Property int Day {get;}
    DayOfWeek Property System.DayOfWeek DayOfWeek {get;}
    DayOfYear Property int DayOfYear {get;}
    Hour Property int Hour {get;}
    Kind Property System.DateTimeKind Kind {get;}
    Millisecond Property int Millisecond {get;}
    Minute Property int Minute {get;}
    Month Property int Month {get;}
    Second Property int Second {get;}
    Ticks Property long Ticks {get;}
    TimeOfDay Property timespan TimeOfDay {get;}
    Year Property int Year {get;}
    DateTime ScriptProperty System.Object DateTime {get=if ((& { Set-StrictMode -Version 1; $this.DisplayHint }) -ieq "Date")...

    As you can see, there are a lot of methods. However, there are a couple of methods that are "hidden". This means that Get-Member won't actually show these methods. However, they can be discovered manually at the powershell prompt, or you can go to the MSDN documentation. (I usually just search for MSDN and the object type.. like msdn system.datetime. (Manual discovery is just typing in the object type, followed by two colons and hitting tab to see what comes up. That should show you most if not all the properties and methods for that object. (i.e. type in [datetime]:: at the powershell prompt and hit tab to see what you come up with).

    One of the things I found a while back is that the [datetime] object has a couple of methods called Parse() and TryParse(). You can read up on these at https://docs.microsoft.com/en-us/dotnet/api/system.datetime?view=netframework-4.7.2#methods.  The first way to use Parse() is to feed it a string that looks like a date or time, and it tries to create a [datetime] object out of it.  TryParse also gives a return of a boolean value indicating if it could parse the string or not.

    All of this goes back to the original question (and what I could get out of it)..  If your data contains text that [i]looks[/i] like a date or time, then you can use [datetime]::Parse(<string>) to get a [datetime] object.

    Here's a few examples (copied & pasted from my own powershell prompt):

    PS C:> [datetime]::parse('2')
    Exception calling "Parse" with "1" argument(s): "String was not recognized as a valid DateTime."
    At line:1 char:1
    + [datetime]::parse('2')
    + ~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : FormatException
    
    PS C:> [datetime]::Parse('2/2019')
    
    Friday, February 1, 2019 12:00:00 AM
    
    PS C:> [datetime]::parse('thursday march 1')
    Exception calling "Parse" with "1" argument(s): "String was not recognized as a valid DateTime because the day of week was incorrect."
    At line:1 char:1
    + [datetime]::parse('thursday march 1')
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : FormatException
    
    PS C:> [datetime]::parse('thursday')
    Exception calling "Parse" with "1" argument(s): "String was not recognized as a valid DateTime."
    At line:1 char:1
    + [datetime]::parse('thursday')
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : FormatException
    
    PS C:> [datetime]::parse('february 5 2019')
    
    Tuesday, February 5, 2019 12:00:00 AM
    
    PS C:> $Sample = [datetime]::Parse('december 13, 2017 9:30pm')
    PS C:> $Sample.GetType()
    
    IsPublic IsSerial Name BaseType
    -------- -------- ---- --------
    True True DateTime System.ValueType
    
    PS C:> $Sample
    
    Wednesday, December 13, 2017 9:30:00 PM
    

    Here are my examples:

    PS C:> [datetime]::parse('2')
    PS C:> [datetime]::Parse('2/2019')
    PS C:> [datetime]::parse('thursday march 1')
    PS C:> [datetime]::parse('thursday')
    PS C:> [datetime]::parse('february 5 2019')
    PS C:> $Sample = [datetime]::Parse('december 13, 2017 9:30pm')
    PS C:> $Sample.GetType()
    PS C:> $Sample

    The first one is a simple string of a digit, and Powershell can't figure it out, so it throws an error.
    The second looks like a month/year, so Powershell returns the [datetime] specified.
    The third one looks like a date to us, but Powershell can't figure it out, and throws and errors.
    The fourth & fifth examples return [datetime] objects.
    The last 3 lines are setting a variable using Parse() and showing that the variable's type *is* really a [datetime] object, and then you see what the interpreted value actually is.

    So all of this explanation, may apply to your question.  You can extract the pieces of the file names or string you have, and can use Parse() or TryParse() to see if they are valid dates, and you can then sort using that.

    [DateTime] also has a couple of extremely handy methods that I use frequently. Get-Date and [DateTime]::Now produce the same object (but the object method is faster than the cmdlet).   There is also a [DateTime]::Today that produces the current date with a time of midnight.

    PS C:> [datetime]::Now
    
    Friday, March 1, 2019 12:47:29 AM
    
    PS C:> [datetime]::Today
    
    Friday, March 1, 2019 12:00:00 AM

    David F.

    • Gordon Robertson 3 years ago

      David...thanks for your reply and your descriptive post.

      You said, in part, "Remember - for powershell, the $ indicates it's a variable. Tim's example just had a typo that you found 🙂

      I don't understand what you are asking here though? Can you give an example of what you are trying to accomplish?"

      A lot of this for me is getting the rust out. I am likely making a mistake when dealing with Powershell in comparing it to the inline compiler in Basic. I am aware of declaring variables in functions but I failed to think of $ as a variable.

      I used Powershell to dump a list of updates in Win 7. I used:

      wmic qfe get hotfixid >> c:\list.txt and it produced a list of all updates in c:\list.txt

      I used other instructions to have Powershell dump the same list with the dates they were installed. I would like to employ the wusa instruction to uninstall updates automatically back to a certain date.

      So I have to get Powershell to read the list in list.txt and uninstall them from the most recent update back a certain number of updates.

      I could do it by hand in Control Panel\Programs and Features but it gets cumbersome. I would like to learn how to write scripts in Powershell and I think this would be a good way to learn.

      Right now, I am lacking the overall understanding of what Powershell is meant to do. In the old days of computer, I used the inline Basic compiler in the field to position heads on a disk drive.

      In the example I used above:

      wmic qfe get hotfixid >> c:\list.txt

      obviously Powershell knows about Windows updates. 'wmic' suggests that WMI is the source, but I have not studied WMI enough to fully understand what it's about.

  5. You are correct about WMIC.. that is the commandline tool for WMI.

    Ultimately, Powershell is a command line shell, similar to cmd.exe/command.com.  However, its capabilities and power is far beyond cmd and is much more like Linux shells (bash, zsh, etc.).  The powershell scripts are like batch files at their heart, but from a power/capability perspective, they are much more like a full blown programming language.  One of the most critical aspects of Powershell is that literally [i]everything[/i] is an object.  What you see on the screen is a representation of the object.  I am one of many that highly recommend Don Jones' Learn Powershell in a Month of Lunches.  It's basically a series of 1-hour lessons that give you a pretty solid grounding.

    To your specific situation, there is a cmdlet built in specifically to retrieve hotfixes.  It's called Get-Hotfix.  With that you can retrieve the hotfixes that are installed.  Here is an example of the output.. (sanitized) Computer is the actual computername.

    Source        Description      HotFixID      InstalledBy          InstalledOn
    ------        -----------      --------      -----------          -----------
    COMPUTER      Update           KB2693643     NT AUTHORITY\SYSTEM  11/13/2018 12:00:00 AM
    COMPUTER      Update           KB4043292     NT AUTHORITY\SYSTEM  3/15/2018 12:00:00 AM
    COMPUTER      Update           KB4049011     NT AUTHORITY\SYSTEM  3/15/2018 12:00:00 AM
    COMPUTER      Update           KB4054590     Domain\UserName      11/12/2018 12:00:00 AM
    COMPUTER      Update           KB4073543     NT AUTHORITY\SYSTEM  11/2/2018 12:00:00 AM
    COMPUTER      Update           KB4093432     NT AUTHORITY\SYSTEM  11/1/2018 12:00:00 AM
    COMPUTER      Update           KB4132649     NT AUTHORITY\SYSTEM  11/30/2018 12:00:00 AM
    COMPUTER      Security Update  KB4465660     NT AUTHORITY\SYSTEM  12/16/2018 12:00:00 AM
    COMPUTER      Security Update  KB4480979     NT AUTHORITY\SYSTEM  2/1/2019 12:00:00 AM
    COMPUTER      Security Update  KB4486458     NT AUTHORITY\SYSTEM  2/1/2019 12:00:00 AM
    COMPUTER      Security Update  KB4480973     NT AUTHORITY\SYSTEM  2/1/2019 12:00:00 AM

    Now, here I'm assigning a variable to a hotfix, and then looking at the properties of that object.

    C:\> $hf = Get-HotFix -Id kb2693643
    C:\> $hf | Get-Member
    
    
       TypeName: System.Management.ManagementObject#root\cimv2\Win32_QuickFixEngineering
    
    Name                MemberType     Definition
    ----                ----------     ----------
    PSComputerName      AliasProperty  PSComputerName = __SERVER
    Caption             Property       string Caption {get;set;}
    CSName              Property       string CSName {get;set;}
    Description         Property       string Description {get;set;}
    FixComments         Property       string FixComments {get;set;}
    HotFixID            Property       string HotFixID {get;set;}
    InstallDate         Property       string InstallDate {get;set;}
    InstalledBy         Property       string InstalledBy {get;set;}
    Name                Property       string Name {get;set;}
    ServicePackInEffect Property       string ServicePackInEffect {get;set;}
    Status              Property       string Status {get;set;}
    __CLASS             Property       string __CLASS {get;set;}
    __DERIVATION        Property       string[] __DERIVATION {get;set;}
    __DYNASTY           Property       string __DYNASTY {get;set;}
    __GENUS             Property       int __GENUS {get;set;}
    __NAMESPACE         Property       string __NAMESPACE {get;set;}
    __PATH              Property       string __PATH {get;set;}
    __PROPERTY_COUNT    Property       int __PROPERTY_COUNT {get;set;}
    __RELPATH           Property       string __RELPATH {get;set;}
    __SERVER            Property       string __SERVER {get;set;}
    __SUPERCLASS        Property       string __SUPERCLASS {get;set;}
    PSStatus            PropertySet    PSStatus {__PATH, Status}
    ConvertFromDateTime ScriptMethod   System.Object ConvertFromDateTime();
    ConvertToDateTime   ScriptMethod   System.Object ConvertToDateTime();
    InstalledOn         ScriptProperty System.Object InstalledOn {get=if ([environment]::osversion.version.build -ge 7000)...

    As you can see, it shows a lot of properties for the hotfix.  One of the key things about this, is that with the pipeline, you can make use of various properties of the objects in various ways.  The cmd prompt has a pipeline, but its much more primitive than Powershell.  In Powershell, the pipeline is a continuing path of operations for the objects that are sent down it.  Each object in powershell has a number of properties and methods, so one of the key concepts for Powershell is "filter left".  That means that you want to send the minimum amount of information down the pipeline which eases your memory burden.  So, let's look at your task at hand..

    First, let's get your list of hotfixes, and sort them from most recent backwards:

    Get-Hotfix | Sort-Object -Property InstalledOn

    Now, let's get a count of hotfixes

    Get-HotFix | Sort-Object -Property InstalledOn | measure-object

    Now, are you looking to uninstall them from a particular date?  If that's the case, we don't have to parse out the text, we can just use the InstalledOn property.  That property is a [DateTime] object, which gives us all kinds of properties and methods.

    PS C:> $hf.InstalledOn | Get-Member
    
       TypeName: System.DateTime
    
    Name                 MemberType     Definition
    ----                 ----------     ----------
    Add                  Method         datetime Add(timespan value)...

    So, lets put it to use.. and grab the hotfixes from this year..

    Get-HotFix | Where-Object { $_.InstalledOn -ge '1/1/2019' }

    Because InstalledOn is a [DateTime] property and '1/1/2019' is a string, Powershell tries (and succeeds) in automatically converting the string to a [DateTime] object and the -ge (greater than or equal to), compares them and it then returns the objects representing the hotfixes that were installed this year.

    But, we're sending down all kinds of things down the pipeline that we don't care about.  With our filtering left policy, we really only need the name and ID of the hotfix.  So, by filtering left, we create a [i]custom object[/p] that contains just the properties we need:

    PS C:\> Get-HotFix | Select-Object -property HotfixID,InstalledOn | Where-Object { $_.InstalledOn -gt '1/1/2019' }
    
    HotfixID  InstalledOn
    --------  -----------
    KB4480979 2/1/2019 12:00:00 AM
    KB4486458 2/1/2019 12:00:00 AM
    KB4480973 2/1/2019 12:00:00 AM

    These objects are not System.Management.ManagementObject#root\cimv2\Win32_QuickFixEngineering type objects anymore.  But, the wusa.exe utility is not an object oriented utility, it just works with strings.

    So.. if we just wanted to uninstall these hotfixes, we would do this:

    PS C:\> Get-HotFix | Select-Object -property HotfixID,InstalledOn | Where-Object { $_.InstalledOn -gt '1/1/2019' } | ForEach-Object { wusa.exe /uninstall /kb $_.HotfixID /log /norestart }

    The key thing to this is we use the ForEach-Object because wusa.exe is not a powershell cmdlet, and doesn't support the pipeline, so we just tell it to handle these objects one at a time.  The other key item is the $_ variable.  This always means 'the object that is currently in the pipeline'.  And because Powershell is object-oriented, we use the dot notation to get the property ($_.InstalledOn).

    Hopefully this can get you going 🙂

    David F.

  6. Gordon Robertson 3 years ago

    David....I really appreciate you going to all the effort, in such detail. I am able to follow you and you revealed what I was looking for. I had not realized Powershell was that powerful and able to list properties that have functions listed with them as to how to operate on them.

    Pretty amazing stuff. I need time to digest this stuff. Thanks again, and I hope your effort is appreciated by others.

    avatar
  7. I'm glad to help 🙂  I'm probably at the top-end of beginner status, and I can see just how much I don't know.  I took Don Jones' advice - if you want to learn, teach it 🙂  I'm finding out that's definitely true.

    David F.

  8. Gordon Robertson 3 years ago

    David...another technique is to write it down. Even if you scrap the notes, explain it to yourself on paper without paraphrasing. If you have to paraphrase, write it in your own words.

    There seems to be a link between writing thoughts by hand and having the material understood and retained.

  9. Absolutely.. if my handwriting weren't so bad, I'd do that a lot more.. 🙂  But, I do take typed up notes all the time for *exactly* that reason.. When I type it up, it sets in my brain a lot more solidly.  😀

    David F.

  10. Karthikeyan 2 years ago

    Hi All ,

    I have data in CSV file format  like "Total duration : 1 hours 40 minutes"  

    Here total duration is label "Total duration" and "1 hours 40 minutes" is value 

    I want to convert above value like this  "Total duration : 100 "  

    Can any one help on this

  11. guy mayer 1 year ago

    hi David,

    I'm passing a phone number when the phone rings to a CRM via keystrokes as I have no control of the phone output or the CRM itself.  

    I need to Format the number string from "07850905301" to "7850 905 301" How can I archive this ??

     

    I have added my code below ... 

    Thanks in advance ...

    Guy

    Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
    [string]$Number = "NoNumber"
    $Number = $args[0]
    $wshell = New-Object -ComObject wscript.shell;
    $wshell.AppActivate('Light Blue')
    Sleep 1
    $wshell.SendKeys('+^f')
    $wshell.SendKeys($Number)
    $wshell.SendKeys('~')
    exit

Leave a reply

Please enclose code in pre tags

Your email address will not be published. Required fields are marked *

*

© 4sysops 2006 - 2021

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account