Showing posts with label PowerShell. Show all posts
Showing posts with label PowerShell. Show all posts

2/08/2016

Azure PowerShell: New-AzureRmAutomationCredential : Input string was not in a correct format.

 

Not an obvious error message:

New-AzurermAutomationCredential -AutomationAccountName "PStest" -Name "myPsredential"

New-AzurermAutomationCredential : Input string was not in a correct format.

image

Turns out it means you already have an Azure Automation credential with that name (“myPsCredential” in this example).

 

Wasted some time google/binging that one!

.

1/14/2016

Azure: PowerShell to List All Blobs in Storage

 

I have an Azure account for development and testing purposes that I want to keep as clean as possible. Part of my routine is clearing out unneeded blobs in the Storage Accounts. To do this using the Portal UI would take a long time… so PowerShell to the rescue.

I thought there would be a quick like piped command something like this:
Get-AzureStorageAccount | Get-AzureStorageContainer | Get-AzureStorageBlob

But no such luck. There’s extra steps to access the Storage Key and to create an Azure Storage Context object needed.

# optional!
$PreviousVerbosePreference = $VerbosePreference
$PreviousWarningPreference = $WarningPreference
$VerbosePreference = "SilentlyContinue"
$WarningPreference = "SilentlyContinue"


# if not alreay logged in to your Azure account...
# Add-AzureAccount
# if more than one subscription
# Select-AzureSubscription -SubscriptionName ????

Get-AzureStorageAccount |
  foreach {

    $acct = $_.label; $storageKey = (Get-AzureStorageKey -StorageAccountName $acct ).Primary;

    $ctx = New-AzureStorageContext -StorageAccountName $acct
-StorageAccountKey $storageKey;

    Get-AzureStorageContainer -Container * -Context $ctx } |

  foreach { $container = $_.Name; $_ } |

  Get-AzureStorageBlob |

  Select {$_.context.StorageAccountName}, {$container}, name,blobtype,length |

  Format-Table -autosize

# optional!
$VerbosePreference = $PreviousVerbosePreference

Select @{label="Storage Account";expression={$_.context.StorageAccountName}},
       @{label="Container";expression={$container}},
       name,
       blobtype,
       @{label="Bytes";expression={"{0,20:N0}" -f $_.length}} |

$WarningPreference = $PreviousWarningPreference

 

And if you like pretty columns then replace the Select line with this:

Select @{label="Storage Account";expression={$_.context.StorageAccountName}},
       @{label="Container";expression={$container}},
       name,
       blobtype,
       @{label="Bytes";expression={"{0,20:N0}" -f $_.length}} |

 

There’s got to be a better way to do this. So post any better solution as a comment!

 

Total storage?

Replace the Format-Table line with “Measure-Object -Property length -Sum” and you can get a file count and total bytes. (Don’t combine this with the “pretty columns” change!)

.

1/03/2016

“Unable to display this Web Part” after XSLT Customization

The following applies to SharePoint 2013, 2016 and SharePoint Online.

 

The Error

“Unable to display this Web Part. To troubleshoot the problem, open this Web page in a Microsoft SharePoint Foundation-compatible HTML editor such as Microsoft SharePoint Designer. If the problem persists, contact your Web server administrator.”

image

The above error shows up in SharePoint 2013 and later when doing multi-level grouping with Data Form Web Parts. With the removal of many of the design features from SharePoint Designer 2013, I doubt there are too many people creating new XSLT customization. But if you are upgrading from 2010 or trying to implement a 2010 style customization then you many run into this error.

 

The Cause and the Fix

If you dig into the error logs you will find that this is reported as “Error while executing web part: System.StackOverflowException”. Turns out though that it is a timeout of the XSLT parser and has been around for quite a while. The fix is pretty easy, if you are on premises, just run a tiny PowerShell script from the SharePoint Management Shell.

image

$farm = Get-SPFarm
$farm.XsltTransformTimeOut = 10
$farm.Update()

Some of the articles say to increase it from the default of 1 second to 5 seconds. In my test environment I typically needed to increase it to 10 seconds. If you monitor the CPU on the server you will see that at least on lab-type virtual machines that a page load where you have this issue does put quite a load on the CPU.

SharePoint Online?  No joy for you! It appears that the default is 1 second, and you can’t change it.

 

There’s been a number of articles on the topic, mostly in the SP 2010 world:

http://thechriskent.com/tag/xslttransformtimeout/

http://blogs.msdn.com/b/joerg_sinemus/archive/2012/03/07/xslt-and-timeout-problem-when-transforming-runs-more-than-one-second.aspx

and many more: http://www.bing.com/search?q=xslttransformtimeout+sharepoint

 

.

1/01/2016

Views.Add() Cannot find an overload for "Add" and the argument count: "8".

 

I wrote a PowerShell script to create views. It worked in PowerShell 3 on SharePoint 2013. It failed in PowerShell 2 on SharePoint 2010.

To play it safe, I copied values from an existing view to insure the correct data types…

$web = Get-SPWeb http://sharepoint/sites/training
$list = $web.lists["Announcements22"]
$v = $list.views[0]
$list.Views.add("TestView",$v.ViewFields,$v.query,30,$true,$false,$v.Type,$false)

image

As I can count to 8 (usually) and I made sure the data types were correct, I then wasted a lot of time google/binging the error message.

So I then did the obvious thing for a developer, I fired up Visual Studio. And… found that there’s a datatype weirdness on the ViewFields parameter! The Add method is expecting System.Collections.Specialized.StringCollection while the View object actually returns Microsoft.SharePoint.SPViewFieldCollection.

The type conversion works in PowerShell 3:

image

But does not work in PowerShell 2:

image

 

My workaround? 

Use a handy method built into the Microsoft.SharePoint.SPViewFieldCollection type: ToStringCollection().

image

I could also have created the StringCollection object and copied the strings over using ForEach.

image

 

So why did it work in PowerShell 3 and not PowerShell 2? No idea! I’m guessing the “smarts” behind type conversion has improved. While the two collection objects are different (SPViewFieldCollection includes a .View property), the Items collection of both contain simple Strings.

 

.

12/06/2015

Get short lists of PowerShell cmdlets

 

I write a lot of documentation and I’m always looking for ways to make lists of things easier to read. Long lists of PowerShell commands have always been a problem as they usually should be sorted by the noun. That’s easy enough, but still can consume a lot of space on paper, and still not be too readable, especially when I want to see all the things I can do with a “user”, a “group” or some other object where I have a lot of cmdlets with the same noun.

For example, there are 135 AD cmdlets on my machine. By default Get-Command orders them by verb. But what are all of things I can do with a "user" or "group"?

image

We can sort on the Noun property, but we still get 135 lines of output:

image

 

So here is my solution… and while I'm happy with the results, I think the script is kind of ugly.

Get-Command *-ad* | Group Noun | 
  foreach { $_.Group | 
    foreach -Begin { $x = @{ noun = $_.Group[0].Noun; verb = ""} } 
            -Process { $x.verb += $_.Verb + "," } 
            -End {$x.verb = $x.verb.substring(0,$x.verb.length-1); $x; } } | 
  sort {$_.noun} | select {$_.noun}, {$_.verb} | ft -AutoSize

image

And now I can see at a glance that I can Get, New, Remove and Set. (And not Add or Delete!)

image

 

.

12/03/2015

SharePoint: Generate a report of inactive sites and owners

This article is for SharePoint 2007, 2010, 2013 and 2016 on premises. (2007 users see the note at the end of the article.)

Cleaning up inactive sites is a common best practice administrator activity. Finding these sites and getting a list of who to contact can take a bit of work. Here's a little PowerShell script to generate a report of all inactive sites, their Site Collection Administrators and their Full Control users.

 

Inactive Site?

Each web has a property named LastItemModifiedDate that can be used as one criteria for site activity. I say "one criteria" as the site may not have had been updated in months, but users still visit the site and view the content every day. In the scripts below we check for the inactivity using a Where that tests against a calculated date:

Where { $_.LastItemModifiedDate -lt ((Get-Date).AddMonths(-9)) }

You can change the test date by using AddDays, AddMonths and AddYears with negative numbers to "go back in time". The example above looks for webs not updated in the last 9 months.

Note: The LastItemModifiedDate (and all other internal SharePoint dates) is in GMT. To convert to local time use ".ToLocalTime()".

image

 

Create a report…

The following script generates a report that lists each web, last updated date, Site Collection Administrators and Full Control users. Note that if you added an Active Directory group with Full Control, only the group name will be listed, not all of the member users.

image

Get-SPSite -Limit All | 
  Get-SPWeb -Limit All | 
  Where { $_.LastItemModifiedDate -lt ((Get-Date).AddMonths(-9)) } |
  foreach {
    # the URL
    ""   #blank line
    $_.url
    "  LastItemModifiedDate: " + $_.LastItemModifiedDate
    "  Web has unique permissions: " + $_.HasUniquePerm

    # the Site Collection Administrators
    " Site Collection Administrators:"
    foreach ($user in $_.SiteAdministrators)
    {      
       "  " + $user.DisplayName + " " + $user.UserLogin
    }

    # full control users
    " Full Control Users:"
    foreach ($user in $_.Users)
    {
       if ( $_.DoesUserHavePermissions($user,[Microsoft.SharePoint.SPBasePermissions]::FullMask) )      
       { 
         "  " + $user.DisplayName + " " + $user.UserLogin
       }
    }
  }

 

Create a customized SPWeb object for further pipelining…

If you would rather have an output that can be piped on to other cmdlets then use the following script. It adds a PowerShell NoteProperty to each SPWeb object named FullControlUsers can be accessed as if it was a built-in property.

Get-SPSite -Limit All | 
  Get-SPWeb -Limit All | 
  Where { $_.LastItemModifiedDate -lt ((Get-Date).AddMonths(-9)) } |
  foreach {
  
    $TTNusers = @();   #empty collection

    foreach ($user in $_.Users)
    {
       if ( $_.DoesUserHavePermissions($user,[Microsoft.SharePoint.SPBasePermissions]::FullMask) )      
       { 
         $TTNusers += $user;  # add to the collection
       }
    }

    # add the new property
    $_ | Add-Member -type NoteProperty -name FullControlUsers -value $TTNusers;

    # forward the modified SPWeb object on through the piepline.
    $_;

  } | 
  Select Url, SiteAdministrators, FullControlUsers 

image

Or maybe change the "Select" to "Format-List":

image

 

Performance Tip

If this script is run during business hours on a large farm you could impact your users. Consider adding a Start-Sleep cmdlet just after the foreach to insert a small delay between webs. But of course, that will make your script take longer to complete.

image

.

For SharePoint 2007

Replace:

Get-SPSite -Limit All | Get-SPWeb -Limit All |

With:

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Administration")
$webapp = [Microsoft.SharePoint.Administration.SPWebApplication]::Lookup("http://maxsp2013wfe")
$webapp.sites | Select -ExpandProperty AllWebs |

 

..

11/28/2015

SharePoint Content Type Inheritance

This article applies to SharePoint 2010, 2013 and 2016.

If you have worked around SharePoint for a while then you have heard the phrase "Everything is a list…". If everything is a list then everything should be an "item", right? Turns out that that is almost a fact. With the exception of only a handful of Content Types, they all inherit from"Item". In the end everything inherits from a base type named "System". The listing below is from a 2013 publishing site with a few extra features enabled to find as many Content Types as possible. The 2016 list is very similar, but is missing some of the Business Intelligence content types (Excel Services?).

A few examples:

  • Task <- Item <- System
  • Document <- Item <- System
  • Video <- System Media Collection <- Document Set <- Document Collection Folder <- Folder <- Item <- System

What does not inherit from Item?

  • Common Indicator Columns <- System  (hidden)
  • And the types that inherit from it:
    • Excel based Status Indicator <- Common Indicator Columns <- System
    • Fixed Value based Status Indicator <- Common Indicator Columns <- System
    • SharePoint List based Status Indicator <- Common Indicator Columns <- System
    • SQL Server Analysis Services based Status Indicator <- Common Indicator Columns <- System

 

    PowerShell to the rescue… again.

    To dump the hierarchy of Content Types I wrote a little PowerShell script that uses a recursive function. Just edit the URL to your site and you can get your list of Content Types.

    If you wanted to see the inheritance pattern another way, add the ID of the Content Type to your output, or just do a test like the following and note the pattern in the IDs:

      $web.ContentTypes | sort id | Select id, name

     

    The PowerShell script:

    function Get-CTypeParent ($ctype, $TTNstr)
    {
      if ($ctype.name -NE "System") {
       $TTNstr = $TTNstr + " <- " + $ctype.parent.name;
       $TTNstr = Get-CTypeParent $ctype.parent $TTNstr 
       }
      return $TTNstr;
    }
    
    $site = Get-SPSite http://yourserver/sites/yourSite
    $web = $site.RootWeb
    
    $web.ContentTypes | sort Group, Name | 
      group Group | 
        foreach { $_.Group  | 
                         foreach 
                           -Begin {"`n" + $_.Name} 
                           -Process { $str="  " + $_.Name ;  Get-CTypeParent $_ $str } 
                }
    

     

    The list of Content Types and their family history!

    This list is from SharePoint 2013. The 2016 list is very similar, but is missing some of the Business Intelligence content types (Excel Services?).

    _Hidden
      Administrative Task <- Task <- Item <- System
      Approval Workflow Task (en-US) <- SharePoint Server Workflow Task <- Workflow Task <- Task <- Item <- System
      Collect Feedback Workflow Task (en-US) <- SharePoint Server Workflow Task <- Workflow Task <- Task <- Item <- System
      Collect Signatures Workflow Task (en-US) <- SharePoint Server Workflow Task <- Workflow Task <- Task <- Item <- System
      Common Indicator Columns <- System
      Design File <- Document <- Item <- System
      Device Channel <- Item <- System
      Device Channel Mappings <- Document <- Item <- System
      Display Template <- Document <- Item <- System
      Display Template Code <- Display Template <- Document <- Item <- System
      Document Collection Folder <- Folder <- Item <- System
      DomainGroup <- Item <- System
      Health Analyzer Report <- Item <- System
      Health Analyzer Rule Definition <- Item <- System
      InfoPath Form Template <- Document <- Item <- System
      Office Data Connection File <- Document <- Item <- System
      Page Output Cache <- Item <- System
      PerformancePoint Base <- Item <- System
      PerformancePoint Monitoring Document Type <- Document <- Item <- System
      Person <- Item <- System
      Project Policy <- Item <- System
      Published Link <- Item <- System
      Publishing Approval Workflow Task (en-US) <- SharePoint Server Workflow Task <- Workflow Task <- Task <- Item <- System
      Reusable HTML <- Item <- System
      Reusable Text <- Item <- System
      RootOfList <- Folder <- Item <- System
      Rule <- Item <- System
      SharePoint Server Workflow Task <- Workflow Task <- Task <- Item <- System
      SharePointGroup <- Item <- System
      Signatures Workflow Task Deprecated <- SharePoint Server Workflow Task <- Workflow Task <- Task <- Item <- System
      System
      System Master Page <- Document <- Item <- System
      System Media Collection <- Document Set <- Document Collection Folder <- Folder <- Item <- System
      System Page <- Document <- Item <- System
      System Page Layout <- Document <- Item <- System
      Translation Package <- Document <- Item <- System
      Translation Status <- Document <- Item <- System
      Universal Data Connection File <- Document <- Item <- System
      User Workflow Document <- Document <- Item <- System
      Workflow History <- Item <- System
      Workflow Task <- Task <- Item <- System
      WorkflowServiceDefinition <- Item <- System
      WorkflowServiceSubscription <- Item <- Systemvi
     
    Business Intelligence
      Excel based Status Indicator <- Common Indicator Columns <- System
      Fixed Value based Status Indicator <- Common Indicator Columns <- System
      Report <- Document <- Item <- System
      Report Document <- Document <- Item <- System
      SharePoint List based Status Indicator <- Common Indicator Columns <- System
      SQL Server Analysis Services based Status Indicator <- Common Indicator Columns <- System
      Web Part Page with Status List <- Document <- Item <- System
     
    Community Content Types
      Category <- Item <- System
      Community Member <- Site Membership <- Item <- System
      Site Membership <- Item <- System
     
    Digital Asset Content Types
      Audio <- Rich Media Asset <- Document <- Item <- System
      Image <- Rich Media Asset <- Document <- Item <- System
      Rich Media Asset <- Document <- Item <- System
      Video <- System Media Collection <- Document Set <- Document Collection Folder <- Folder <- Item <- System
      Video Rendition <- Rich Media Asset <- Document <- Item <- System
     
    Display Template Content Types
      Control Display Template <- Display Template <- Document <- Item <- System
      Filter Display Template <- Display Template <- Document <- Item <- System
      Group Display Template <- Display Template <- Document <- Item <- System
      Item Display Template <- Display Template <- Document <- Item <- System
      JavaScript Display Template <- Document <- Item <- System
     
    Document Content Types
      Basic Page <- Document <- Item <- System
      Document <- Item <- System
      Dublin Core Columns <- Document <- Item <- System
      Form <- Document <- Item <- System
      Link to a Document <- Document <- Item <- System
      List View Style <- Document <- Item <- System
      Master Page <- Document <- Item <- System
      Master Page Preview <- Document <- Item <- System
      Picture <- Document <- Item <- System
      Web Part Page <- Basic Page <- Document <- Item <- System
      Wiki Page <- Document <- Item <- System
     
    Document Set Content Types
      Document Set <- Document Collection Folder <- Folder <- Item <- System
     
    Folder Content Types
      Discussion <- Folder <- Item <- System
      Folder <- Item <- System
      Summary Task <- Folder <- Item <- System
     
    Group Work Content Types
      Circulation <- Item <- System
      Holiday <- Item <- System
      New Word <- Item <- System
      Official Notice <- Item <- System
      Phone Call Memo <- Item <- System
      Resource <- Item <- System
      Resource Group <- Item <- System
      Timecard <- Item <- System
      Users <- Item <- System
      What's New Notification <- Item <- System
     
    List Content Types
      Announcement <- Item <- System
      Comment <- Item <- System
      Contact <- Item <- System
      East Asia Contact <- Item <- System
      Event <- Item <- System
      Issue <- Item <- System
      Item <- System
      Link <- Item <- System
      Message <- Item <- System
      Post <- Item <- System
      Reservations <- Event <- Item <- System
      Schedule <- Event <- Item <- System
      Schedule and Reservations <- Event <- Item <- System
      Task <- Item <- System
      Workflow Task (SharePoint 2013) <- Task <- Item <- System
     
    Page Layout Content Types
      Article Page <- Page <- System Page <- Document <- Item <- System
      Catalog-Item Reuse <- Page <- System Page <- Document <- Item <- System
      Enterprise Wiki Page <- Page <- System Page <- Document <- Item <- System
      Error Page <- Page <- System Page <- Document <- Item <- System
      Project Page <- Enterprise Wiki Page <- Page <- System Page <- Document <- Item <- System
      Redirect Page <- Page <- System Page <- Document <- Item <- System
      Welcome Page <- Page <- System Page <- Document <- Item <- System
     
    PerformancePoint
      PerformancePoint Dashboard <- PerformancePoint Base <- Item <- System
      PerformancePoint Data Source <- PerformancePoint Monitoring Document Type <- Document <- Item <- System
      PerformancePoint Filter <- PerformancePoint Base <- Item <- System
      PerformancePoint Indicator <- PerformancePoint Base <- Item <- System
      PerformancePoint KPI <- PerformancePoint Base <- Item <- System
      PerformancePoint Report <- PerformancePoint Base <- Item <- System
      PerformancePoint Scorecard <- PerformancePoint Base <- Item <- System
     
      
    Publishing Content Types
      ASP NET Master Page <- System Master Page <- Document <- Item <- System
      Html Master Page <- ASP NET Master Page <- System Master Page <- Document <- Item <- System
      Html Page Layout <- Page Layout <- System Page Layout <- Document <- Item <- System
      Page <- System Page <- Document <- Item <- System
      Page Layout <- System Page Layout <- Document <- Item <- System
     
    Special Content Types
      Unknown Document Type <- Document <- Item <- System

     

    The List Sorted By Ancestor

    Change the last line of the script to the following and you can see another pattern in the inheritance.

    $web.contenttypes | sort group, name | group group | foreach { $_.Group  | foreach -begin {"`n" + $_.Name} -process { $str="  " + $_.name ;  Get-CTypeParent $_ $str } }

    System ->   Item
    System -> Item ->   Announcement
    System -> Item ->   Circulation
    System -> Item ->   Comment
    System -> Item ->   Contact
    System -> Item ->   Device Channel
    System -> Item ->   Document
    System -> Item ->   DomainGroup
    System -> Item ->   East Asia Contact
    System -> Item ->   Event
    System -> Item ->   Folder
    System -> Item ->   Health Analyzer Report
    System -> Item ->   Health Analyzer Rule Definition
    System -> Item ->   Holiday
    System -> Item ->   Issue
    System -> Item ->   Link
    System -> Item ->   Message
    System -> Item ->   New Word
    System -> Item ->   Official Notice
    System -> Item ->   Page Output Cache
    System -> Item ->   PerformancePoint Base
    System -> Item ->   Person
    System -> Item ->   Phone Call Memo
    System -> Item ->   Post
    System -> Item ->   Published Link
    System -> Item ->   Resource
    System -> Item ->   Resource Group
    System -> Item ->   Reusable HTML
    System -> Item ->   Reusable Text
    System -> Item ->   Rule
    System -> Item ->   SharePointGroup
    System -> Item ->   Task
    System -> Item ->   Timecard
    System -> Item ->   Users
    System -> Item ->   What's New Notification
    System -> Item ->   Workflow History
    System -> Item ->   WorkflowServiceDefinition
    System -> Item ->   WorkflowServiceSubscription
    System -> Item -> Document ->   Basic Page
    System -> Item -> Document ->   Design File
    System -> Item -> Document ->   Device Channel Mappings
    System -> Item -> Document ->   Display Template
    System -> Item -> Document ->   Dublin Core Columns
    System -> Item -> Document ->   Form
    System -> Item -> Document ->   InfoPath Form Template
    System -> Item -> Document ->   JavaScript Display Template
    System -> Item -> Document ->   Link to a Document
    System -> Item -> Document ->   List View Style
    System -> Item -> Document ->   Master Page
    System -> Item -> Document ->   Master Page Preview
    System -> Item -> Document ->   Office Data Connection File
    System -> Item -> Document ->   PerformancePoint Monitoring Document Type
    System -> Item -> Document ->   Picture
    System -> Item -> Document ->   Report Document
    System -> Item -> Document ->   Rich Media Asset
    System -> Item -> Document ->   System Master Page
    System -> Item -> Document ->   System Page
    System -> Item -> Document ->   System Page Layout
    System -> Item -> Document ->   Translation Package
    System -> Item -> Document ->   Translation Status
    System -> Item -> Document ->   Universal Data Connection File
    System -> Item -> Document ->   Unknown Document Type
    System -> Item -> Document ->   User Workflow Document
    System -> Item -> Document ->   Wiki Page
    System -> Item -> Document -> Basic Page ->   Web Part Page
    System -> Item -> Document -> Display Template ->   Control Display Template
    System -> Item -> Document -> Display Template ->   Display Template Code
    System -> Item -> Document -> Display Template ->   Filter Display Template
    System -> Item -> Document -> Display Template ->   Group Display Template
    System -> Item -> Document -> Display Template ->   Item Display Template
    System -> Item -> Document -> PerformancePoint Monitoring Document Type ->   PerformancePoint Data Source
    System -> Item -> Document -> Rich Media Asset ->   Audio
    System -> Item -> Document -> Rich Media Asset ->   Image
    System -> Item -> Document -> Rich Media Asset ->   Video Rendition
    System -> Item -> Document -> System Master Page ->   ASP NET Master Page
    System -> Item -> Document -> System Master Page -> ASP NET Master Page ->   Html Master Page
    System -> Item -> Document -> System Page ->   Page
    System -> Item -> Document -> System Page -> Page ->   Article Page
    System -> Item -> Document -> System Page -> Page ->   Catalog-Item Reuse
    System -> Item -> Document -> System Page -> Page ->   Enterprise Wiki Page
    System -> Item -> Document -> System Page -> Page ->   Error Page
    System -> Item -> Document -> System Page -> Page ->   Redirect Page
    System -> Item -> Document -> System Page -> Page ->   Welcome Page
    System -> Item -> Document -> System Page -> Page -> Enterprise Wiki Page ->   Project Page
    System -> Item -> Document -> System Page Layout ->   Page Layout
    System -> Item -> Document -> System Page Layout -> Page Layout ->   Html Page Layout
    System -> Item -> Event ->   Reservations
    System -> Item -> Event ->   Schedule
    System -> Item -> Event ->   Schedule and Reservations
    System -> Item -> Folder ->   Discussion
    System -> Item -> Folder ->   Document Collection Folder
    System -> Item -> Folder ->   RootOfList
    System -> Item -> Folder ->   Summary Task
    System -> Item -> Folder -> Document Collection Folder ->   Document Set
    System -> Item -> Folder -> Document Collection Folder -> Document Set ->   System Media Collection
    System -> Item -> Folder -> Document Collection Folder -> Document Set -> System Media Collection ->   Video
    System -> Item -> PerformancePoint Base ->   PerformancePoint Dashboard
    System -> Item -> PerformancePoint Base ->   PerformancePoint Filter
    System -> Item -> PerformancePoint Base ->   PerformancePoint Indicator
    System -> Item -> PerformancePoint Base ->   PerformancePoint KPI
    System -> Item -> PerformancePoint Base ->   PerformancePoint Report
    System -> Item -> PerformancePoint Base ->   PerformancePoint Scorecard
    System -> Item -> Task ->   Administrative Task
    System -> Item -> Task ->   Workflow Task
    System -> Item -> Task ->   Workflow Task (SharePoint 2013)
    System -> Item -> Task -> Workflow Task ->   PSWApprovalTask
    System -> Item -> Task -> Workflow Task ->   SharePoint Server Workflow Task
    System -> Item -> Task -> Workflow Task -> SharePoint Server Workflow Task ->   Approval Workflow Task (en-US)
    System -> Item -> Task -> Workflow Task -> SharePoint Server Workflow Task ->   Collect Feedback Workflow Task (en-US)
    System -> Item -> Task -> Workflow Task -> SharePoint Server Workflow Task ->   Collect Signatures Workflow Task (en-US)
    System -> Item -> Task -> Workflow Task -> SharePoint Server Workflow Task ->   Publishing Approval Workflow Task (en-US)
    System -> Item -> Task -> Workflow Task -> SharePoint Server Workflow Task ->   Signatures Workflow Task Deprecated

     


     

    System ->   Item
    System -> Item ->   Announcement
    System -> Item ->   Circulation
    System -> Item ->   Comment
    System -> Item ->   Contact
    System -> Item ->   Device Channel
    System -> Item ->   Document
    System -> Item ->   DomainGroup
    System -> Item ->   East Asia Contact
    System -> Item ->   Event
    System -> Item ->   Folder
    System -> Item ->   Health Analyzer Report
    System -> Item ->   Health Analyzer Rule Definition
    System -> Item ->   Holiday
    System -> Item ->   Issue
    System -> Item ->   Link
    System -> Item ->   Message
    System -> Item ->   New Word
    System -> Item ->   Official Notice
    System -> Item ->   Page Output Cache
    System -> Item ->   PerformancePoint Base
    System -> Item ->   Person
    System -> Item ->   Phone Call Memo
    System -> Item ->   Post
    System -> Item ->   Published Link
    System -> Item ->   Resource
    System -> Item ->   Resource Group
    System -> Item ->   Reusable HTML
    System -> Item ->   Reusable Text
    System -> Item ->   Rule
    System -> Item ->   SharePointGroup
    System -> Item ->   Task
    System -> Item ->   Timecard
    System -> Item ->   Users
    System -> Item ->   What's New Notification
    System -> Item ->   Workflow History
    System -> Item ->   WorkflowServiceDefinition
    System -> Item ->   WorkflowServiceSubscription
    System -> Item -> Document ->   Basic Page
    System -> Item -> Document ->   Design File
    System -> Item -> Document ->   Device Channel Mappings
    System -> Item -> Document ->   Display Template
    System -> Item -> Document ->   Dublin Core Columns
    System -> Item -> Document ->   Form
    System -> Item -> Document ->   InfoPath Form Template
    System -> Item -> Document ->   JavaScript Display Template
    System -> Item -> Document ->   Link to a Document
    System -> Item -> Document ->   List View Style
    System -> Item -> Document ->   Master Page
    System -> Item -> Document ->   Master Page Preview
    System -> Item -> Document ->   Office Data Connection File
    System -> Item -> Document ->   PerformancePoint Monitoring Document Type
    System -> Item -> Document ->   Picture
    System -> Item -> Document ->   Report Document
    System -> Item -> Document ->   Rich Media Asset
    System -> Item -> Document ->   System Master Page
    System -> Item -> Document ->   System Page
    System -> Item -> Document ->   System Page Layout
    System -> Item -> Document ->   Translation Package
    System -> Item -> Document ->   Translation Status
    System -> Item -> Document ->   Universal Data Connection File
    System -> Item -> Document ->   Unknown Document Type
    System -> Item -> Document ->   User Workflow Document
    System -> Item -> Document ->   Wiki Page
    System -> Item -> Document -> Basic Page ->   Web Part Page
    System -> Item -> Document -> Display Template ->   Control Display Template
    System -> Item -> Document -> Display Template ->   Display Template Code
    System -> Item -> Document -> Display Template ->   Filter Display Template
    System -> Item -> Document -> Display Template ->   Group Display Template
    System -> Item -> Document -> Display Template ->   Item Display Template
    System -> Item -> Document -> PerformancePoint Monitoring Document Type ->   PerformancePoint Data Source
    System -> Item -> Document -> Rich Media Asset ->   Audio
    System -> Item -> Document -> Rich Media Asset ->   Image
    System -> Item -> Document -> Rich Media Asset ->   Video Rendition
    System -> Item -> Document -> System Master Page ->   ASP NET Master Page
    System -> Item -> Document -> System Master Page -> ASP NET Master Page ->   Html Master Page
    System -> Item -> Document -> System Page ->   Page
    System -> Item -> Document -> System Page -> Page ->   Article Page
    System -> Item -> Document -> System Page -> Page ->   Catalog-Item Reuse
    System -> Item -> Document -> System Page -> Page ->   Enterprise Wiki Page
    System -> Item -> Document -> System Page -> Page ->   Error Page
    System -> Item -> Document -> System Page -> Page ->   Redirect Page
    System -> Item -> Document -> System Page -> Page ->   Welcome Page
    System -> Item -> Document -> System Page -> Page -> Enterprise Wiki Page ->   Project Page
    System -> Item -> Document -> System Page Layout ->   Page Layout
    System -> Item -> Document -> System Page Layout -> Page Layout ->   Html Page Layout
    System -> Item -> Event ->   Reservations
    System -> Item -> Event ->   Schedule
    System -> Item -> Event ->   Schedule and Reservations
    System -> Item -> Folder ->   Discussion
    System -> Item -> Folder ->   Document Collection Folder
    System -> Item -> Folder ->   RootOfList
    System -> Item -> Folder ->   Summary Task
    System -> Item -> Folder -> Document Collection Folder ->   Document Set
    System -> Item -> Folder -> Document Collection Folder -> Document Set ->   System Media Collection
    System -> Item -> Folder -> Document Collection Folder -> Document Set -> System Media Collection ->   Video
    System -> Item -> PerformancePoint Base ->   PerformancePoint Dashboard
    System -> Item -> PerformancePoint Base ->   PerformancePoint Filter
    System -> Item -> PerformancePoint Base ->   PerformancePoint Indicator
    System -> Item -> PerformancePoint Base ->   PerformancePoint KPI
    System -> Item -> PerformancePoint Base ->   PerformancePoint Report
    System -> Item -> PerformancePoint Base ->   PerformancePoint Scorecard
    System -> Item -> Task ->   Administrative Task
    System -> Item -> Task ->   Workflow Task
    System -> Item -> Task ->   Workflow Task (SharePoint 2013)
    System -> Item -> Task -> Workflow Task ->   PSWApprovalTask
    System -> Item -> Task -> Workflow Task ->   SharePoint Server Workflow Task
    System -> Item -> Task -> Workflow Task -> SharePoint Server Workflow Task ->   Approval Workflow Task (en-US)
    System -> Item -> Task -> Workflow Task -> SharePoint Server Workflow Task ->   Collect Feedback Workflow Task (en-US)
    System -> Item -> Task -> Workflow Task -> SharePoint Server Workflow Task ->   Collect Signatures Workflow Task (en-US)
    System -> Item -> Task -> Workflow Task -> SharePoint Server Workflow Task ->   Publishing Approval Workflow Task (en-US)
    System -> Item -> Task -> Workflow Task -> SharePoint Server Workflow Task ->   Signatures Workflow Task Deprecated

     

     

     

     

     

    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/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

    .

    11/07/2015

    Windows Explorer Search – Learn something new every day…

     

    I was searching through around 400 folders with thousands of files for all of the files that contained "_files" in their names. Should be easy… open Windows Explorer and type in the search box *_files* and wait… but I got back every file as if I had typed "*".

    Is the underline a wildcard?

    Not according to the documentation I can find, and it does not otherwise behave like a wildcard. For example, searching for "f_le" or "*f_le*" did not find anything.

    Is the underline ignored?

    Seems like it. Except… if you include a file type in the search then the underline is treated as an ordinary character or if you use the FileName property.

    Two solutions:

    Add a filetype wild card:   *_file*.*   

    Search using a property name:   filename:*_file*    (but don't add ".*" if you are also looking for folders!)

     

    What about good ole DOS?

    Works exactly as expected.   DIR *_files* /s   .

     

    What about PowerShell

    Also works exactly as expected.   dir -Filter *_files* –Recurse

    I should have started with PowerShell anyway as the next step was to rename these files! Smile

     

    What creates file names that include "_file"?

    Internet Explorer when you use File, Save As, Web Page Complete.

     

    .

    11/04/2015

    The specified module 'Microsoft.Online.SharePoint.PowerShell' was not loaded

     

    When trying to load the SharePoint Online PowerShell module into the ISE or an existing shell you may get the error below. Simple problem with a non-obvious error message… The fix is easy… after installing the SharePoint Online Management Shell, run PowerShell or the ISE as Administrator.

    PS C:\> Import-Module Microsoft.Online.SharePoint.PowerShell -DisableNameChecking
    Import-Module : The specified module 'Microsoft.Online.SharePoint.PowerShell' was not loaded because no valid 
    module file was found in any module directory.
    At line:1 char:1
    + Import-Module Microsoft.Online.SharePoint.PowerShell -DisableNameChecking
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : ResourceUnavailable: (Microsoft.Online.SharePoint.PowerShell:String) [Import-Mo 
       dule], FileNotFoundException
        + FullyQualifiedErrorId : Modules_ModuleNotFound,Microsoft.PowerShell.Commands.ImportModuleCommand

    10/16/2015

    SharePoint / PowerShell List Item Update Note

     

    Sometimes it's the forests and sometimes it's the trees…

     

    I have gotten so used to using shortcuts like chaining of properties in PowerShell that I forget some of my .Net fundamentals.

    The Title never gets updated in this little script. What's wrong?

    $web = Get-SPWeb "http://maxsp2013wfe/sites/training"
    $list = $web.Lists["Announcements"]
    $list.items[3]["Title"]="Test Title"
    $list.items[3].Update()

    Line 3 creates a new SPListItem object in RAM and sets its Title property.
    Line 4 creates a new (but different) SPListItem object and calls .Update() on it.

    Duh!

     

    This works:

    $web = Get-SPWeb "http://maxsp2013wfe/sites/training"
    $list = $web.Lists["Announcements"]
    $item = $list.items[3]
    $item["Title"]="Test Title"
    $item.Update()

    Create the SPListItem object once, change a property and then save it.

    And I teach this stuff!  Sad smile

    .

    9/20/2015

    Upload a File to SharePoint Using PowerShell

     

    A while back I posted an article on downloading files from SharePoint using PowerShell (see here) that generated a few questions about uploading files. So… here's a few uploading scripts. Don't stop here though, there are many other examples on the web. Google/Bing is your friend!

     

    An Upload with Metadata Script

    This script not only uploads files, but lets you add metadata.

    # Set a few variables
    $file = "C:\test\myTestFile.txt"
    $TTNwebUrl = "http://server/sites/yoursite"
    $library = "Team Documents"
    $overWriteExisting = $True #or add new version if versioning enabled
    
    # do a little SharePoint setup
    $web = Get-SPWeb $TTNwebUrl
    $files = $web.GetFolder($library).Files
    $fileNameForLibrary = $file.Substring($file.LastIndexOf("\")+1) 
    
    # read the file
    $data = Get-ChildItem $file
    
    # add any needed metadata
    $metadata = @{ "Project ID" = "A-200"; "Region" = "North" }
    
    # or if no metadata needed: $metadata = @{}
    
    # do the upload (the following is one line)
    $newfile = $files.Add($library + "/" + $fileNameForLibrary, $data.OpenRead(), $metadata, $overWriteExisting)

     

    And if you are a "one liner" PowerShell scripter:

    (Get-SPWeb "http://server/sites/yoursite").GetFolder("Team Documents").Files.Add("Team Documents/myTestFile.txt", (Get-ChildItem "C:\test\myTestFile.txt").OpenRead(), $True)

    And with metadata:
    (Get-SPWeb "http://server/sites/yoursite").GetFolder("Team Documents").Files.Add("Team Documents/myTestFile.txt", (Get-ChildItem "C:\test\myTestFile.txt").OpenRead(), @{ "Project ID" = "A-200"; "Region" = "North" }, $True)

     

    Upload an Attachment with a New List Item

    I generally recommend linking from a list item to a file in a library, but if you want to add attachments to a list item, here's a sample script:

    # Set a few variables
      $TTNweb = Get-SPWeb "http://yourServer/sites/yourSite";
      $list = $TTNweb.lists["yourListName"];
      $filePath = "C:\SampleDocs\yourSampleFile.JPG";
    
    # Create a new list item:
      $item = $list.items.Add(); 
      $item["Title"] = "Test Title";
      # set any addition metadata 
      $item.Update();
    
    # Upload the file:
      $bytes = [System.IO.File]::ReadAllBytes($filePath);
      $item.Attachments.Add([System.IO.Path]::GetFileName($filePath), $bytes);
      $item.Update();

     

     

    Looking for a PowerShell course for SharePoint administrators and auditors?

    SharePoint 2010 and 2013 Auditing and Site Content Administration using PowerShell

    https://www.microsoft.com/en-us/learning/course.aspx?cid=55095A

    Or you can attend my class in Cincinnati (locally or remotely)!
    http://www.maxtrain.com/Classes/ClassInfo.aspx?Id=119394

    .

    8/18/2015

    Cincinnati PowerShell User Group Meeting

     

    Register here: (free!) http://www.meetup.com/TechLife-Cincinnati/events/224705451/

    Cincinnati PowerShell Users group – August Meeting

    When: August 27th
    Where: Max Technical Training
    Mason, OH

    PS C:\> Get-PSUG | where {$_.City -eq Cincinnati}

    The Cincinnati PowerShell user group is back and under new management!  Last meeting was great with Ed Wilson as our presenter, I hope you all got as fired up about scripting as we did!

    Come join us as we dive into….

    Version Control?  That's for Developers, not Admins!!

    Does your version control look like this?!?!?

    We'll cover different ways to approach source control with PowerShell, why we as System Administrators need it, and why the idea of "infrastructure-as-code" is getting so much traction these days.

     

    Sponsor!

    SAPIEN Technologies will be sponsoring the Cincinnati PowerShell User Group meeting and will be supplying the pizza!

    .

    6/01/2015

    Cincinnati PowerShell User Group Meeting this week!


    Info. and RSVP here: http://meetu.ps/2JkRsx


    The PowerShell User Group is back! (But the future is up to you!)


         PS C:\> Get-Speaker | Plan-Meeting | ShowUp-AndLearn!


    Sponsor:  SAPIEN Technologies
    is supplying the food!
    Ed Wilson "The Scripting Guy" from Microsoft will be here to help us (re)kickoff the PowerShell User Group. If you would like to see future meetings, place your vote by showing up for this meeting!
    Wednesday, June 3rd 6:30 PM at MAX Technical Training. (Food and networking starts at 6:00!)



    Speaker: Ed Wilson "The Scripting Guy"
    Title: Garbage in, Garbage out: Data grooming with Windows PowerShell
    Everyone has heard the old adage, "garbage in, garbage out" when talking about databases, or other online data storage / retrieval systems. But do you know that Windows PowerShell can help you with your problem? In this session, Microsoft Scripting Guy Ed Wilson talks about using Windows PowerShell to perform data grooming. He shows how cleaning up names, street addresses, cities, states, and even zip codes by using basic string manipulation techniques. By focusing directly on the data transformation itself, he extracts principles that can be used regards of the database, or other data storage system. After focusing on the individual components of the process, he puts the whole thing into a single script for transforming the sample data. This session is heavy with live demonstration.

    Bio
    Ed Wilson is the Microsoft Scripting Guy, and writes the daily Hey Scripting Guy blog. He is the co-founder of PowerShell Saturday, and the Charlotte PowerShell User Group. He is a frequent speaker at conferences, user groups and other places where groups of computer people may be found. He has written books about every version of Windows PowerShell, as well as other books related to automation and operating systems.  His most recent book is Windows PowerShell Best Practices.


    .

    4/21/2015

    Run SharePoint 2013 Search Reports from PowerShell–Part 2!

     

    First… see the original article here: http://techtrainingnotes.blogspot.com/2015/04/run-sharepoint-2013-search-reports-from.html

    What if you want reports for each site collection? All we need is another function, a "Get-SPSIte –Limit ALL" and some code to generate unique file names and we can now create hundreds to thousands of Excel files!!! (Please make sure you never fill your server's drives with this!)

     

    # This is the path to write the reports to:
    $path = "c:\SearchReports\"
    
    
    function Get-SPSearchReports ($farmurl, $searchreport, $path)
    {
      # Report names and IDs
      $Number_of_Queries          = "21be5dff-c853-4259-ab01-ee8b2f6590c7"
      $Top_Queries_by_Day         = "56928342-6e3b-4382-a14d-3f5f4f8b6979"
      $Top_Queries_by_Month       = "a0a26a8c-bf99-48f4-a679-c283de58a0c4"
      $Abandoned_Queries_by_Day   = "e628cb24-27f3-4331-a683-669b5d9b37f0"
      $Abandoned_Queries_by_Month = "fbc9e2c1-49c9-44e7-8b6d-80d21c23f612"
      $No_Result_Queries_by_Day   = "5e97860f-0595-4a07-b6c2-222e784dc3a8"
      $No_Result_Queries_by_Month = "318556b1-cabc-4fad-bbd5-c1bf8ed97ab1"
      $Query_Rule_Usage_by_Day    = "22a16ae2-ded9-499d-934a-d2ddc00d406a"
      $Query_Rule_Usage_by_Month  = "f1d70093-6fa0-4701-909d-c0ed502e3df8"
    
      # create a unique filename for each site and report
      $sitename = $farmurl.Replace("http://","").Replace("https://","")
      $sitename = $sitename.substring(0,$sitename.IndexOf("/_layouts"))
      $sitename = $sitename.Replace("/","_").Replace(":","_").Replace(".","_")
    
      $filename = $path + $sitename + " " + 
                  (Get-Variable $searchreport).Name + " " + 
                  (Get-Date -Format "yyyy-mm-dd") + ".xlsx"
      #Write-Host "Creating $filename"
    
      $reportid = (Get-Variable $searchreport).Value
    
      $TTNcontent = "&__EVENTTARGET=__Page&__EVENTARGUMENT=ReportId%3D" + $reportid
    
      # setup the WebRequest
      $webRequest = [System.Net.WebRequest]::Create($farmurl)
      $webRequest.UseDefaultCredentials = $true
      $webRequest.Accept = "image/jpeg, application/x-ms-application, image/gif, application/xaml+xml, image/pjpeg, application/x-ms-xbap, */*"
      $webRequest.ContentType = "application/x-www-form-urlencoded"
      $webRequest.Method = "POST"
    
      $encodedContent = [System.Text.Encoding]::UTF8.GetBytes($TTNcontent)
        $webRequest.ContentLength = $encodedContent.length
        $requestStream = $webRequest.GetRequestStream()
        $requestStream.Write($encodedContent, 0, $encodedContent.length)
        $requestStream.Close()
    
      # get the data
      [System.Net.WebResponse] $resp = $webRequest.GetResponse();
        $rs = $resp.GetResponseStream();
        #[System.IO.StreamReader] $sr = New-Object System.IO.StreamReader -argumentList $rs;
        #[byte[]]$results = $sr.ReadToEnd();
        [System.IO.BinaryReader] $sr = New-Object System.IO.BinaryReader -argumentList $rs;
        [byte[]]$results = $sr.ReadBytes(10000000);
    
      # write the file
      Set-Content $filename $results -enc byte
    }
    
    
    function Get-SPSearchReportsForSite ($url, $path)
    {
    
      Get-SPSearchReports $url "Number_of_Queries" $path
      Get-SPSearchReports $url "Top_Queries_by_Day" $path
      Get-SPSearchReports $url "Top_Queries_by_Month" $path
      Get-SPSearchReports $url "Abandoned_Queries_by_Day" $path
      Get-SPSearchReports $url "Abandoned_Queries_by_Month" $path
      Get-SPSearchReports $url "No_Result_Queries_by_Day" $path
      Get-SPSearchReports $url "No_Result_Queries_by_Month" $path
      Get-SPSearchReports $url "Query_Rule_Usage_by_Day" $path
      Get-SPSearchReports $url "Query_Rule_Usage_by_Month" $path
    
    }
    
    
    Get-SPSite -Limit All | 
      foreach   {
        $url = $_.Url + "/_layouts/15/Reporting.aspx?Category=AnalyticsSiteCollection";
        #$path = (you might do a custom path for each set of reports)
    
        Write-Host "Getting files for $url"
        Get-SPSearchReportsForSite $url $path
      }
    
    

    4/20/2015

    Run SharePoint 2013 Search Reports from PowerShell


    Update: SharePoint 2016 version here: http://techtrainingnotes.blogspot.com/2018/02/run-sharepoint-2013-and-2016-search.html



    Update! Need these reports for every site collection in the farm? See Part 2: http://techtrainingnotes.blogspot.com/2015/04/run-sharepoint-2013-search-reports-from_21.html

    In my Search Administration class I stress that admins should dump the search reports on a regular basis as the data is only kept in detail for 14 days and in summary form for 35 months. But who wants to both run these reports at least once every 14 days, even they can remember to do so. So, PowerShell to the rescue… Schedule this script to run each weekend and your work is done.
    The following script works for on premise SharePoint 2013. To work with Office 365 you will have to figure out how to include your credentials. The example included here works on premises by using "UseDefaultCredentials = $true".
    After lots of hacking, detective work (see below) and just plain trial and error, here's the script:
    # This is the URL from the Central Admin Search Service Usage Reports page:
    $url = "http://yourCentralAdminURL/_layouts/15/reporting.aspx?Category=AnalyticsSearch&appid=ed39c68b%2D7276%2D46f7%2Db94a%2D4ae7125cf567"  
    
    # This is the path to write the reports to (must exist):
    $path = "c:\SearchReports\"
    
    
    
    
    function Get-SPSearchReports ($farmurl, $searchreport, $path)
    {
      # TechTrainingNotes.blogspot.com
    
      # Report names and IDs
      $Number_of_Queries          = "21be5dff-c853-4259-ab01-ee8b2f6590c7"
      $Top_Queries_by_Day         = "56928342-6e3b-4382-a14d-3f5f4f8b6979"
      $Top_Queries_by_Month       = "a0a26a8c-bf99-48f4-a679-c283de58a0c4"
      $Abandoned_Queries_by_Day   = "e628cb24-27f3-4331-a683-669b5d9b37f0"
      $Abandoned_Queries_by_Month = "fbc9e2c1-49c9-44e7-8b6d-80d21c23f612"
      $No_Result_Queries_by_Day   = "5e97860f-0595-4a07-b6c2-222e784dc3a8"
      $No_Result_Queries_by_Month = "318556b1-cabc-4fad-bbd5-c1bf8ed97ab1"
      $Query_Rule_Usage_by_Day    = "22a16ae2-ded9-499d-934a-d2ddc00d406a"
      $Query_Rule_Usage_by_Month  = "f1d70093-6fa0-4701-909d-c0ed502e3df8"
    
    
      $filename = $path + (Get-Variable $searchreport).Name + " " + (Get-Date -Format "yyyy-mm-dd")  + ".xlsx"
      $reportid = (Get-Variable $searchreport).Value
    
      $TTNcontent = "&__EVENTTARGET=__Page&__EVENTARGUMENT=ReportId%3D" + $reportid
    
      # setup the WebRequest
      $webRequest = [System.Net.WebRequest]::Create($farmurl)
      $webRequest.UseDefaultCredentials = $true
      $webRequest.Accept = "image/jpeg, application/x-ms-application, image/gif, application/xaml+xml, image/pjpeg, application/x-ms-xbap, */*"
      $webRequest.ContentType = "application/x-www-form-urlencoded"
      $webRequest.Method = "POST"
    
      $encodedContent = [System.Text.Encoding]::UTF8.GetBytes($TTNcontent)
        $webRequest.ContentLength = $encodedContent.length
        $requestStream = $webRequest.GetRequestStream()
        $requestStream.Write($encodedContent, 0, $encodedContent.length)
        $requestStream.Close()
    
      # get the data
      [System.Net.WebResponse] $resp = $webRequest.GetResponse();
        $rs = $resp.GetResponseStream();
        #[System.IO.StreamReader] $sr = New-Object System.IO.StreamReader -argumentList $rs;
        #[byte[]]$results = $sr.ReadToEnd();
        [System.IO.BinaryReader] $sr = New-Object System.IO.BinaryReader -argumentList $rs;
        [byte[]]$results = $sr.ReadBytes(10000000);
    
      # write the file
      Set-Content $filename $results -enc byte
    }
    
    
    
    Get-SPSearchReports $url "Number_of_Queries" $path
    Get-SPSearchReports $url "Top_Queries_by_Day" $path
    Get-SPSearchReports $url "Top_Queries_by_Month" $path
    Get-SPSearchReports $url "Abandoned_Queries_by_Day" $path
    Get-SPSearchReports $url "Abandoned_Queries_by_Month" $path
    Get-SPSearchReports $url "No_Result_Queries_by_Day" $path
    Get-SPSearchReports $url "No_Result_Queries_by_Month" $path
    Get-SPSearchReports $url "Query_Rule_Usage_by_Day" $path
    Get-SPSearchReports $url "Query_Rule_Usage_by_Month" $path
     
    


    The Detective Work…

    I could not find anything documented on how the reports are called or details on things like the report GUIDs. So here's how I got there:
    • Go the search reports page in Central Admin and press F12 to open the Internet Explorer F12 Developer Tools then:
      • Click the Network tab and click the play button to start recording.
      • Click one of the report links.
      • Double-click the link generated for the report in the F12 pane to open up the details.
      • Make note of the URL (It's the same as the report page!)
      • Note the Accept, and Content-Type Request Headers.
      • Click the Request Body tab.
      • Stare at 3000 characters in that string until your head really hurts, or until you recognize most of what is there is the normal page postback stuff like VIEWSTATE. So we need to find what's unique in the string. (It's the Report IDs.)
      • Click on each of the nine reports and copy out the report IDs.
      • With a lot of trial and error figure out what the minimum string needed is to generate the reports. (It's ""&__EVENTTARGET=__Page&__EVENTARGUMENT=ReportId" plus the report id.)
      • Find out how to do an HTTP POST using PowerShell. (Steal most of it from here: http://www.codeproject.com/Articles/846061/PowerShell-Http-Get-Post.)
      • Find some other needed .Net code and convert the C# to PowerShell.
      • Fill in some gaps with PowerShell putty …….

    .

          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.