April 2011 - Posts
מה זה בכלל PowerShell? למה אני צריך את זה? בנות אוהבות את זה?
מה אם אף פעם לא כתבתי אפילו שורת פקודה אחת? אני בכלל לא מפתח – זה נוגע אלי?
המון שאלות אה?
על כל זאת ועוד נדבר במפגש הבא של קבוצת הדיון שייערך ב- 25/05/2011 בשעה 15:45 במשרדי מיקרוסופט, רעננה.
את יתר הפרטים תוכלו למצוא בהזמנה כאן: http://sbu.co.il/forum_posts.asp?TID=420&PID=1905
אין צורך בידע מוקדם, הביאו רק את עצמכם, ראש פתוח ומצב רוח טוב, השאר עלינו.
נתראה במפגש!
Learn Windows PowerShell in a Month of Lunches is a newly designed tutorial for system administrators. Just set aside one hour a day -- lunchtime would be perfect -- for a month, and you'll be automating administrative tasks in a hurry. Author Don Jones combines his in-the-trenches experience with a unique teaching style to help you master the effective parts of PowerShell quickly and painlessly.
Who Should Read It
The book is written for administrators, not developers.
What's Inside
- Learn PowerShell 2 from the beginning-no experience required!
- Written especially for administrators, not developers
- Practical examples and reusable techniques in every concise 1-hour lesson
About the Author
Don Jones has more than 15 years of IT experience, is the author of more than 35 books, and is a speaker at technology conferences such as Microsoft TechEd and Windows Connections. He's a multiple-year recipient of Microsoft's MVP award and is a technical guide for PowerShell for WindowsITPro.
Only for the next 24 hours you can use the lunchtoday promode and get a 50% discount!
The Get-Date cmdlet lets us create, convert, and format date strings to DateTime .NET objects. However, there’s one thing it cannot do, convert a date string which is not a format it expects (defines by your system locale). For example, if your current culture is en-US you can pass a date string in the format of MM/dd/yyyy to the –Date parameter and Get-date will convert it to a DateTime object:
PS > Get-Date -Date 4/13/2011
Wednesday, April 13, 2011 12:00:00 AM
On the other hand, if we pass a string in the format of dd/MM/yyyy it fails:
PS > Get-Date -Date 13/4/2011
Get-Date : Cannot bind parameter 'Date'. Cannot convert value "13/4/2011" to type "System.DateTime". Error: "String was not recognized as a valid DateTime."
As you can see from the above error, Get-Date complains that "13/4/2011" was not in the correct format. A common case to this kind of date strings is when you have a third party application that writes date strings, not in the format of your locale, to log files. The only way to convert those strings to a valid DateTime object is to use the ParseExact static method of the DateTime .NET class. The ParseExact method is an overloaded member (we can invoke it in three ways, each with its own set of arguments). Instead of using the method directly I wrapped the first overload in an Advanced Function, ConvertFrom-DateString.
function ConvertFrom-DateString
{
[OutputType('System.DateTime')]
[CmdletBinding(DefaultParameterSetName='Culture')]
param(
[Parameter(
Mandatory=$true,
Position=0,
ValueFromPipeline=$true,
HelpMessage='A string containing a date and time to convert.'
)]
[System.String]$Value,
[Parameter(
Mandatory=$true,
Position=1,
HelpMessage='The required format of the date string value'
)]
[Alias('format')]
[System.String]$FormatString,
[Parameter(ParameterSetName='Culture')]
[System.Globalization.CultureInfo]$Culture=$null,
[Parameter(Mandatory=$true,ParameterSetName='InvariantCulture')]
[switch]$InvariantCulture
)
process
{
if($PSCmdlet.ParameterSetName -eq 'InvariantCulture')
{
$Culture = [System.Globalization.CultureInfo]::InvariantCulture
}
Try
{
[System.DateTime]::ParseExact($Value,$FormatString,$Culture)
}
Catch [System.FormatException]
{
Write-Error "'$Value' is not in the correct format."
}
Catch
{
Write-Error $_
}
}
<#
.SYNOPSIS
Converts a string representation of a date.
.DESCRIPTION
Converts the specified string representation of a date and time to its
DateTime equivalent using the specified format and culture-specific format
information. The format of the string representation must match the specified
format exactly.
.PARAMETER Value
A string containing a date and time to convert.
.PARAMETER FormatString
The required format of the date string value. If FormatString defines a
date with no time element, the resulting DateTime value has a time of
midnight (00:00:00).
If FormatString defines a time with no date element, the resulting DateTime
value has a date of DateTime.Now.Date.
If FormatString is a custom format pattern that does not include date or
time separators (such as "yyyyMMdd HHmm"), use the invariant culture
(e.g [System.Globalization.CultureInfo]::InvariantCulture), for the provider
parameter and the widest form of each custom format specifier.
For example, if you want to specify hours in the format pattern, specify
the wider form, "HH", instead of the narrower form, "H".
The format parameter is a string that contains either a single standard
format specifier, or one or more custom format specifiers that define the
required format of StringFormats. For details about valid formatting codes,
see 'Standard Date and Time Format Strings' (http://msdn.microsoft.com/en-us/library/az4se3k1.aspx)
or 'Custom Date and Time Format Strings' (http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx).
.PARAMETER Culture
An object that supplies culture-specific formatting information about the
date string value. The default value is null. A value of null corresponds
to the current culture.
.PARAMETER InvariantCulture
Gets the CultureInfo that is culture-independent (invariant). The invariant
culture is culture-insensitive. It is associated with the English language
but not with any country/region.
.EXAMPLE
ConvertFrom-DateString -Value 'Sun 15 Jun 2008 8:30 AM -06:00' -FormatString 'ddd dd MMM yyyy h:mm tt zzz' -InvariantCulture
Sunday, June 15, 2008 5:30:00 PM
This example converts the date string, 'Sun 15 Jun 2008 8:30 AM -06:00',
according to the specifier that defines the required format.
The InvariantCulture switch parameter formats the date string in a
culture-independent manner.
.EXAMPLE
'jeudi 10 avril 2008 06:30' | ConvertFrom-DateString -FormatString 'dddd dd MMMM yyyy HH:mm' -Culture fr-FR
Thursday, April 10, 2008 6:30:00 AM
In this example a date string, in French format (culture). The date string
is piped to ConvertFrom-DateString. The input value is bound to the Value
parameter. The FormatString value defines the required format of the date
string value. The result is a DateTime object that is equivalent to the date
and time contained in the Value parameter, as specified by FormatString and
Culture parameters.
.EXAMPLE
ConvertFrom-DateString -Value 'Sun 15 Jun 2008 8:30 AM -06:00' -FormatString 'ddd dd MMM yyyy h:mm tt zzz'
Sunday, June 15, 2008 5:30:00 PM
Converts the date string specified in the Value parameter with the
custom specifier specified in the FormatString parameter. The result
DateTime object format corresponds to the current culture.
.INPUTS
System.String
You can pipe a string that contains a date and time to convert.
.OUTPUTS
System.DateTime
.NOTES
Author: Shay Levy
Blog : http://PowerShay.com
.LINK
http://msdn.microsoft.com/en-us/library/w2sa9yss.aspx
#>
}
ConvertFrom-DateString is decorated with Comment Based Help so you can use the Get-Help cmdlet to get help for its parameters as well as code examples. Let’s see how we can use the function to convert a date string to a DateTime object.
PS> 'Tue Mar 29 14:49:04 2011' | ConvertFrom-DateString -FormatString 'ddd MMM dd HH:mm:ss yyyy'
Tuesday, March 29, 2011 2:49:04 PM
The Value parameter accept pipeline input so we can pipe the string to the function. We also specify the format of the string, specifying each element position in the Format-String parameter. We didn’t specify the Culture parameter so the result is a DateTime object in the current culture of the local system. To get more help on .NET format specifiers, see "DateTimeFormatInfo Class" in the MSDN (Microsoft Developer Network) library at http://go.microsoft.com/fwlink/?LinkId=143638
Here’s another example with a French date string. This time we specify the string in the Value parameter and we also use the Culture parameter to tell the function that the string is in the fr-FR culture:
PS > ConvertFrom-DateString –Value 'jeudi 10 avril 2008 06:30' -FormatString 'dddd dd MMMM yyyy HH:mm' -Culture fr-FR
Thursday, April 10, 2008 6:30:00 AM
The function can also be downloaded from the TechNet Script Center Repository.
Enjoy!
When PowerShell starts it creates a bunch of Automatic Variables. One of them is $PWD. $PWD contains a path object that represents the full path of the current directory (provider sensitive). Typically, when you assign a value to a variable, the value is evaluated once and from then on it's "static", each time you call the variable the returned value is always the same. The beauty of $PWD is that its value is calculated each time you call it.
PS> $PWD
Path
----
D:\scripts
PS > Set-Location HKLM:\SOFTWARE
PS > $PWD
Path
----
HKLM:\SOFTWARE
$PWD contains a rich .NET object (System.Management.Automation.PathInfo), not just a string path, so we can also interact directly with its members:
PS > $PWD.Provider.Name
Registry
I was trying to create a variable similar to $PWD ($Now) to get the current date and time, but no matter what I tried, the value of $Now always returned the same date and time. The reason behind creating $Now was this. Let's say you want to get the DayOfWeek value of a DateTime object, what we often do is:
## two lines of code
PS > $date = Get-Date
PS > $date.DayOfWeek
Or
## using a .NET class
PS> [DateTime]::Now.DayOfWeek
Or
## enclosing in parenthesis
PS> (Get-Date).DayOfWeek
I wanted is to use the third example but avoid enclosing Get-Date it in parenthesis. One of the ways I was trying is with a function:
PS > function Now {Get-Date}
It works, I can now get a new fresh DateTime object each time I call the function, but I can't access the result object members without enclosing it in parenthesis:
PS> (Now).DayOfWeek
Ultimately, this is how I wanted it to be:
$Now.DayOfWeek
Simple to use and very short to type. Another thought was to create a new Alias but the result was the same as using a function, parenthesis were required to access object members. So I posted a question to the PowerShell MVP private list and soon enough Lee Holmes, pointed me to this blog post. Here's the code I used to create $Now:
Add-Type -TypeDefinition @"
using System;
using System.Management.Automation;
public class NowVariable : PSVariable
{
public NowVariable ()
: base("Now", 0, ScopedItemOptions.ReadOnly | ScopedItemOptions.AllScope)
{}
public override object Value
{
get
{
return DateTime.Now;
}
}
}
"@
$ExecutionContext.SessionState.PSVariable.Set((New-Object -TypeName NowVariable))
Paste this code into your console and there you have it! A variable that evaluates its value each time you call it.
PS>$Now
Tuesday, April 12, 2011 10:48:41 AM
PS>$Now
Tuesday, April 12, 2011 10:48:43 AM
PS>$Now
Tuesday, April 12, 2011 10:48:45 AM
PS> $Now.DayOfWeek
Tuesday
Now we can access any member of the result DateTime object without parenthesis. Thanks Lee! The next step is to ask the PowerShell team to include $Now in the next version of PowerShell and the way to do that is to file a suggestion on the Microsoft Windows PowerShell Customer Connection website. The PowerShell team review the items suggested by the community and if it has enough votes it will find its (hopefully) way to the next version of PowerShell.
Do you want to have $Now as a new automatic variable in PowerShell 3.0? Vote it up HERE.
UPDATE: Check out this awesome post, by Robert Robelo, where he shows a how to get the same functionality in pure script and it also works in PowerShell v1!