11/17/2015

PowerShell Get-Date vs. [DateTime]

 

The Cincinnati PowerShell User Group (@CincyPowershell) opens each meeting with a review of a cmdlet. Tonight is was Get-Date's turn. Many of the examples were done with both Get-Date and [datetime], with one example showing that only [datetime] supports the IsLeapYear() method. This got me to thinking… (sometimes a painful thing…) and the light bulb lit up over my head. Get-Date returns an instance of the System.DateTime class, i.e. an object, while [datetime] is a reference to the class and provides easy access to the class's static methods.

 

System.DateTime

To be precise, [datetime] is really [System.DateTime], but System is the default name space and PowerShell is not case sensitive (most of the time). And to be precise, Get-Date with no options is the same as[System.DateTime]::Now.

What's with the two colons? They are PowerShell's way to call a static method on a class. So going back to the IsLeapYear() question, it is a static method of the DateTime class. To access it we write [System.DateTime]::IsLeapYear(2016).

 

Get-Date

Get-Date is a cmdlet with many options, but the default option is to return the current date and time. I.e. [System.DateTime]::Now.

The class that an object was created from is also called it's type. So what's the "type" of a date?

image

 

Instances / Objects

If Get-Date returns an instance, how could I do that with [DateTime]? Two ways, use one of the static methods like .Now or .Today, or create a new object using the New-Object cmdlet.

Using the static methods:

$d = [System.DateTime]::Now    (or just [DateTime].Now)

$d = [System.DateTime]::Today  (or just [DateTime].Today)

Using New-Object:

$d = New-Object System.DateTime    (or just DateTime)

The unique aspect of using New-Object with DateTime is that you get back an object with default values for year, month, day, etc. and not today's date. The actual result is "Monday, January 01, 0001 12:00:00 AM".

image

If you want to create a particular date or time, use one of the class's constructors. (See the DateTime Structure link at the end of the article for details.)

image

There's a nice write up about classes, instances, statics here from Don Jones.

 

And just for fun… and only in PowerShell 5.0

Who needs [System.DateTime]?  Just call the static methods off of any DateTime object! The following all produce the same result, keeping in mind that Get-Date adds the additional overhead of retrieving the current date, and then ignoring it.

(Get-Date)::IsLeapYear(2016)

$d = Get-Date
$d::IsLeapYear(2016)

$d = [System.DateTime]::Now
$d::IsLeapYear(2016)

 

What about PowerShell 3.0?

The examples for 5.0 do not work with 3.0. We have to ask for the "class", i.e. it's Type.

(Get-Date).GetType()::IsLeapYear(2016)

$d = Get-Date
$d.GetType()::IsLeapYear(2016)

$d = [System.DateTime]::Now
$d.GetType()::IsLeapYear(2016)

 

What about PowerShell 4.0?

Beats me! (Don't have a copy in front of me right now.)

 

Discover the Static Methods and Properties of an Object

Get-Member has a –Static parameter to display the static methods and properties of an object:

Get-Date | Get-Member -Static

image

 

More Fun With Static Methods

Most .Net classes are not exposed in PowerShell as cmdlets.

For example, you might need a new GUID…

[System.Guid]::NewGuid()   will return a new GUID object.

[System.Guid]::NewGuid().toString()   will return a new GUID as a string.

image

How about some Math?

Need the value of PI?

[System.,Math]::PI  (or just [Math]::PI)  It's about 3.14159265358979 according to PowerShell and .Net.

How about the square root of 2?

[Math]::Sqrt(2)  (Let's see… I think it's about 1.4142135623731.)

And of course, the Sine of 45 degrees:

[Math]::sin(0.785398163397448)  (in Radians of course) Oh, about 0.707106781186547.

And doing a little converting from degrees to Radians:

[Math]::sin( [Math]::pi/180*45 )

For more of what the Math class can do, see the Math link at the end of the article. Or, wait for it, use PowerShell:

[Math] | Get-Member  -Static

 

Bottom line… if the C# guys can do it, then so can you!

 

So now you know… 2016 is a leap year!  And at least a dozen different ways!

 

(and a quick 5 minute article took over an hour…)

 

References:

Using Static Classes and Methods
https://technet.microsoft.com/en-us/library/dd347632.aspx

How to Create an Object in PowerShell
http://blogs.msdn.com/b/powershell/archive/2009/03/11/how-to-create-an-object-in-powershell.aspx

DateTime Structure (All of the constructors, methods and properties of DateTime)
https://msdn.microsoft.com/en-us/library/system.datetime(v=vs.110).aspx

A nice write up on class, object, instance and static by Don Jones:
http://powershell.org/wp/2014/09/08/powershell-v5-class-support/

System.Math Class
https://msdn.microsoft.com/en-us/library/system.math(v=vs.110).aspx

 

.

11/16/2015

Add a Crumb Trail to SharePoint 2013

 

Solution #1: Restore the SharePoint 2010 Navigate Up button

See here: http://techtrainingnotes.blogspot.com/2014/06/sharepoint-2013-restoring-2010-navigate.html

[image%255B21%255D.png]

 

Solution 2: Add an always displayed site crumb trail

If you only need a crumb trail to be able to navigate back up to a parent site then we can add a site map control to the master page like this:

<span style="font-size:8pt;">
  <asp:SiteMapPath id="ContentMap2" 
       SkipLinkText="" NodeStyle-CssClass="ms-sitemapdirectional" 
       runat="server"/> 
</span>

Edit your master page, search for "</h1>" and add the HTML above just below the "</h1>".

The result will look like this:

image

 

Solution 3: Add an always displayed site and folder crumb trail

See the link below for a nice solution that reuses the SharePoint:ListSiteMapPath control from the SharePoint 2010 Navigate Up control and reformats it into a single line.

http://www.broculos.net/2013/12/sharepoint-2013-branding-show-folder.html

The result looks like this:

image

Notes:

  • The author of that article was working with a Publishing feature Design Manager master page and wrapped the control inside of an HTML comment block. (<!--   -->) You will not need this for a non-publishing site master paged edited in SharePoint Designer.
  • The article's sample CSS code needs to be placed inside of a linked CSS file or inside of style tags. <style type="text/css">  ,,,  </style>
  • To get the crumb trail display exactly where I wanted it I added it just after the "</h1>" tag in the master page and added this to the article's CSS:
      .my-breadcrumb {
         margin-top:0px;
         margin-left:3px;
         font-size:8pt;
      }

 

Other options

Here's a project that adds a folder crumb trail to library web parts using JS Link: SharePoint 2013: Folder Navigation/Breadcrumb
http://social.technet.microsoft.com/wiki/contents/articles/19713.sharepoint-2013-folder-navigationbreadcrumb.aspx and here: http://ranaictiu-technicalblog.blogspot.com/2013/07/sharepoint-2013-folder-navigation-for.html

The only disadvantage to this solution is that you need to make a change to every list/library/view web part.

 

.

11/14/2015

Sorting Hashtables and SharePoint Properties Lists with PowerShell

 

Sometimes the obvious just does not work… I was doing some work with SharePoint publishing sites, trying to find some of the data in the SPWeb AllProperties property. AllProperties looks like a collection of Names and Values. Actually it is Hashtable object.

My first attempt looked like this:

    $psite.AllWebs[0].AllProperties | sort -Property name

image

The output was random, not sorted as expected. After too long messing with trial and error, I did a web search and found a TechNet "Windows PowerShell Tip of the Week" article with the answer. Hashtable objects and sort just don't work together. We need to get an enumerator for the hash table and work with that…

   $psite.AllWebs[0].AllProperties.GetEnumerator() | sort -Property name

image

That's the output I was looking for!

If you pipe both of the above to Get-Member you will see that the first just returns a Hashtable object that includes a collection of Keys and a collection of Values. The second one, using GetEnumerator, returns a single DictionaryEntry object (one at a time through the pipeline) with a Key and a Value property. Now we have something to sort on!

image

.

Weird SharePoint Icons = Timeout!


Have you ever had a SharePoint page "explode"? Odds are something from the server timed out. In the example below the CSS files never got loaded. The links timed out. A simple refresh should fix it. If it does, let your server admins know about the issue.

BTW, those weird looking icon collections are call image sprites.

image

 

If the refresh does not fix the problem, you may have a broken master page. (Have you been playing around with SharePoint Designer?) You can either use SharePoint Designer to select a working master page or edit your site's URL to take you to the Site Settings page and select one there..
Change:
  http://yourServer/sites/yourSite/Pages/Default.aspx  (or whatever your URL looks like)
to something like:
  http://yourServer/sites/yourSite/_layouts/settings.aspx  (2013 will redirect and add a "15" to the URL.)

From that page you can select another master page or make other changes to fix the issue. In some cases you even need to open SharePoint Designer to undo the change you made or to select another master page. For a publishing site click Master Pages in the Look and Feel section of the Site Settings page. If you see the following message then you do have a master page problem.

image

In some cases, just clicking OK and selecting the same master page will fix the problem. Otherwise, select Seattle or Oslo and see if that gets your site working again.

Note to spammers!

Spammers, don't waste your time... all posts are moderated. If your comment includes unrelated links, is advertising, or just pure spam, it will never be seen.