CHUVASH.eu

CHunky Universe of Vigourous Astonishing SHarepoint :)

Tag Archives: PowerShell

Export SharePoint List Data To Xml through PowerShell

Today my colleague Johannes Milling wrote an awesome post:

Export SharePoint List Data To XML Directly from the GUI

He uses the old and forgotten RPC-based web service owssvr.dll (that has existed since SharePoint 2003). This url pattern is used to get the xml-formatted list data for a specific ListView:

http://<site_url>/_vti_bin/owssvr.dll?Cmd=Display&List=<list guid>&View=<view guid>&Query=*&XMLDATA=TRUE

To automate this I have written a PowerShell function. All the details are in the comments:

function Export-OIPSPListDataAsXml {
<#
.Synopsis
   Exports list items as xml
.DESCRIPTION
   This function uses a built-in hidden service owssvr.dll in SharePoint
.PARAMETER Web
   SPWeb or a url for the SPWeb object where the list resides
.PARAMETER ListName
   List Name (List Title)
.PARAMETER ViewName
   Name of the List View to export the data
.EXAMPLE
   Export-OIPSPListView -Web http://myawesomesite -ListName "Teddy Bears" -ViewName "All Items"
.EXAMPLE
   Export-OIPSPListView -Web $webInstance -ListName "Top Links" -ViewName "All Items"
.Notes
    Name: Export-OIPSPListDataAsXml
    Author: Anatoly Mironov
    Last Edit: 2014-09-11
    Keywords: SPList, SPWeb, SPListView, Xml
.Link
	http://chuvash.eu
#>
    [CmdLetBinding()]
    param(
	[Parameter(Mandatory=$true)]
    [Microsoft.SharePoint.PowerShell.SPWebPipeBind]$Web,
    [Parameter(Mandatory=$true)]
    [string]$ListName,
    [Parameter(Mandatory=$true)]
    [string]$ViewName)

    $spWeb = $Web.Read()
    $list = $spWeb.Lists[$ListName]
    if (!$list) { throw "List $ListName on web $($spWeb.Url) could not be found" }
    $view = $list.Views[$ViewName]
    if (!$view) { throw "View $ViewName on web $ListName could not be found" }
    $url = "{0}/_vti_bin/owssvr.dll?Cmd=Display&List={1}&View={2}&Query=*&XMLDATA=TRUE" `
            -f $spWeb.Url, $list.ID, $view.ID
    $wc = New-Object Net.WebClient
    $wc.UseDefaultCredentials = $true
    $wc.DownloadString($url)
}

Showing Birthdays and Job Anniversaries in the Newsfeed

anniversary-001

In our project we have a requirement to show birthdays and job anniversaries in the Newsfeed. The solution is simple (when you know it) but there has not been any information about it online, until today. I want to share a few lines of PowerShell code to enable Anniversary notifications in the Newsfeed. This desired piece of code was written by my colleague Emma Degerman. Enjoy:

$job = Get-SPTimerJob | ? { $_.TypeName -like "*.UserProfileChangeJob" }
$job.GenerateAnniversaries = $true
$job.Schedule = [Microsoft.SharePoint.SPSchedule]::FromString("hourly between 55 and 55")
$job.Update()

The code retrieves the Timer Job that changes User Profiles, sets “GenerateAnniversaries” to true, then it updates the schedule to run it before the Activity Feed Timer Job and updates it. By the way, it is only applicable for SharePoint On Premises.

This is it, a quick tip for a great Intranet.

Load git into PowerShell

Just a little productivity tip. If you use git on Windows, you probably already have the Github for Windows application. This application adds the Git Shell:

006-gitshell

The Git Shell will open a PowerShell window and execute shell.ps1 from the Github directory:

007-gitshell

What it won’t do is to load your personal PowerShell profile. I want to use my PowerShell profile that creates some links and adjust the look-and-feel and the promt of the shell. By the way I have published my profile.ps1 as a gist:

I also want to have git in PowerShell available directly. The answer is in the shell.ps1 in the Github folder:

008-gitshell

So add this line to your profile.ps1 as I did:

. (Resolve-Path "$env:LOCALAPPDATA\GitHub\shell.ps1")

That’s it. If you haven’t seen the “DOT” in PowerShell scripts, it is called dot sourcing, it will execute the script and keep all the variables and references within the script.

An alternative

If you do not have Github for Windows, there is another way to load git functionality into PowerShell:

A presentation about PowerShell and SharePoint

Yesterday I had a little presentation about PowerShell basics in the SharePoint context. Here you can see the presentation I’ve published on slideshare. The text is in Swedish.

A PowerShell one liner

PowerShell is powerful. You can write concise, well formulated, functional-style code. Recently I got the following quiz:

You’ve got $100. You have to buy exactly 100 animal, at least 1 dog, 1 cat and 1 mouse. 1 dog costs $15, 1 cat costs $1, 1 mouse costs $0.25.

There can be  many ways to solve it. But look at this one line solution. It is quite impressive what you can do with PowerShell

1..98 | % {
    $dog = $_
    1..98 | % {
      $cat = $_
      @{
        "Dog" = $dog
        "Cat" = $cat
        "Mouse" = 100 - $dog -$cat
      }
    }
  } | ? {
      $_.Mouse -gt 0
  } | ? { $_.Dog * 15 + $_.Cat * 1 + $_.Mouse * 0.25 -eq 100 }

This solution uses ranges, dynamic objects (PSObject), nested for loops, implicit returns and advanced filtering. All that is is out-of-the-box PowerShell.

The CDN concept in SharePoint

How many instances of jquery are there in your SharePoint farm?

 Get-SPWebApplication http://dev `
  | Select -Expand Sites `
  | Select -Expand AllWebs `
  | Select -Expand Lists `
  | Select -Expand Items `
  | ? { $_.Url -match "jquery.*.js" } `
  | select Name, Url

Have you more than two (jquery and jquery-ui), then you have too much. You can save much place and performance by using Content Delivery Network (CDN) links for the resources like javascript, css, fonts and icons. Consider those Content Delivery Networks:

CDN for custom resources

But can we benefit from this CDN concept for our custom resources? I think so, if your farm has ten thousands of site collections, and you deploy javascript files, css files in the Style Library, it would be great to eliminate resource duplicates. So my thougt is to deploy resources to one place. It could be:

  • An external web application static.contoso.com like many web applications do
  • A dedicated site collection for resources cdn.contoso.com with Anonymous access
The CDN concept in Office 365

Have you noticed that Office 365 uses cdn links for almost all SharePoint javascript files that traditionaly were referenced from the _layouts folder

cdn-001

With this I want to raise a question. What do you think about the CDN concept within SharePoint? Have you used it? Have you plans to have it?

Set IE Proxy Server with PowerShell

Today just a quick one-liner tip for PowerShell.  Use this script to set a proxy server in IE Settings. I got the inspiration from Aymeric’s blog:  Scripting : Toggle proxy server in IE settings with PowerShell:

sp AutoConfigUrl "http://proxy.contoso.com" `
   -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings"

By the way sp is just alias for Set-ItemProperty cmdlet:
proxy_002

This corresponds these settings in IE (Tools – Internet Options – Connections – Lan Settings):

proxy_001

It can be useful if you have want to automate this.

AutoSPInstaller: error while stopping the default web site in IIS

get-website-failure

During an installation with AutoSPInstaller on my development machine I ran into a strange issue. I got the following error:

System.IO.FileNotFoundException: Could not load file or assembly ‘Microsoft.IIS.PowerShell.Framework’ or one of its dependencies

I haven’t found any other people having the same problem with the AutoSPInstaller, but I found a similar report on another forum: help.octopusdeploy.com. Maybe I am the only one who gets this error in AutoSPInstaller, if not it can be useful to write the solution down.

The error occurs when the default web site in IIS is stopped. For some reason Get-WebSite cmdlet throws an exception the first time you invoke it, but not the second time.

To get it working I followed the tip from the help.octopusdeploy.com and wrapped the Get-Website code in a try-and-catch, where the same cmdlet was in try and in catch. This line:

$defaultWebsite = Get-Website | Where-Object {$_.Name -eq "Default Web Site" -or $_.ID -eq 1 -or $_.physicalPath -eq "%SystemDrive%\inetpub\wwwroot"} # Try different ways of identifying the Default Web Site, in case it has a different name (e.g. localized installs)

becomes this code (the lines in try and catch are identical):

Try{
    $defaultWebsite = Get-Website | Where-Object {$_.Name -eq "Default Web Site" -or $_.ID -eq 1 -or $_.physicalPath -eq "%SystemDrive%\inetpub\wwwroot"} # Try different ways of identifying the Default Web Site, in case it has a different name (e.g. localized installs)
} Catch [System.IO.FileNotFoundException]{
    $defaultWebsite = Get-Website | Where-Object {$_.Name -eq "Default Web Site" -or $_.ID -eq 1 -or $_.physicalPath -eq "%SystemDrive%\inetpub\wwwroot"}
    Break
}

With this fix I was able to run the whole AutoSPInstaller script. My development machine was a fresh installed Windows Server 2008 R2 SP1 (without any updates).

Leave a comment if you run into the same issue. If so, I’ll try to send a patch to the AutoSPInstaller code.

Update 2013-06-06

This issue was reported to AutoSPInstaller at codeplex and closed as “self-resolved”.

PowerShell: Copy an entire document library from SharePoint 2007 to disk

For a while ago I needed to copy all files from a document library within a SharePoint 2007 site to the hard drive. So I didn’t need to copy files from SharePoint to SharePoint so I couldn’t use the stsadm -o export command or Chris O’Brien’s nice SharePoint Content Deployment Wizard. I came across the SPIEFolder application which should work with SharePoint 2007 and 2010. It has a site on codeplex: spiefolder.codeplex.com, but neither the binary nor the source code can be downloaded from there. After some searching I found the binary in the author’s skydrive. The fact that the source code was not available seemed as an disanvantage because I could not know what code was run. Nevertheless I tried it out and it didn’t work:

spiefolder -o export -url "http://dev/Documents" -directory c:\tolle\Documents –recursive

I got the following error:

The Web application at http://dev/Documents could not be found. Verify that you have typed the URL correctly. If the URL should be serving existing content, the system administrator may need to add a new request URL mapping to the intended application.

So I wrote my own code to copy the documents. To write a console application feels so yesterdayish, so it is written in PowerShell. Even if there are no PowerShell snapins for SharePoint 2007, you have access to the entire Server Object Model, the only thing you have to do is to load the SharePoint assembly:

[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")

Then you can instantiate all SharePoint objects like in C#, but in a PowerShell way:

$site = new-Object Microsoft.SharePoint.SPSite("http://dev")
$web = $site.OpenWeb()

You can even download a module for emulating cmdlets: Get-SPWeb, Get-SPWebApplication and Get-SPFarm, written by Natalia Tsymbalenko (sharing-the-experience.blogspot.com) to get started or just to find some inspiration.

I have created a ps1-script which only does one thing – it copies an entire document library to disk. Much of inspiration to structure the script comes from “Delete-SPListItems” (sharepointryan.com).

Here it is: Pull-Documents.ps1

<#
.Synopsis
    Use Pull-Documents to copy the entire document library to disk
.Description
    This script iterates recursively over all directories and files in a document library and writes binary data to the disk
    The structure is kept as in the Document library
    It is mainly written for SharePoint 2007, but it works even in SharePoint 2010
.Example
    Pull-Document -Url http://dev -Library "Shared Documents"
.Notes
    Name: Pull-Documents.ps1
    Author: Anatoly Mironov
    Last Edit: 2012-12-03
    Keywords: SPList, Documents, Files, SPDocumentLibrary
.Links
    https://sharepointkunskap.wordpress.com
    http://www.bool.se
.Inputs
    None
.Outputs
    None
#Requires -Version 1.0
#>
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)][System.String]$Url = $(Read-Host -prompt "Web Url"),
[Parameter(Mandatory=$true)][System.String]$Library = $(Read-Host -prompt "Document Library")
)
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")

$site = new-object microsoft.sharepoint.spsite($Url)
$web = $site.OpenWeb()
$site.Dispose()

$folder = $web.GetFolder($Library)
$folder # must output it otherwise "doesn't exist" in 2007

if(!$folder.Exists){
    Write-Error "The document library cannot be found"
    $web.Dispose()
    return
}

$directory = $pwd.Path

$rootDirectory = Join-Path $pwd $folder.Name

if (Test-Path $rootDirectory) {
    Write-Error "The folder $Library in the current directory already exists, please remove it"
    $web.Dispose()
    return
}

#progress variables
$global:counter = 0
$global:total = 0
#recursively count all files to pull
function count($folder) {
    if ($folder.Name -ne "Forms") {
        $global:total += $folder.Files.Count
        $folder.SubFolders | Foreach { count $_ }
    }
}
write "counting files, please wait..."
count $folder
write "files count $global:total"

function progress($path) {
    $global:counter++
    $percent = $global:counter / $global:total * 100
    write-progress -activity "Pulling documents from $Library" -status $path -PercentComplete $percent
}

#Write file to disk
function Save ($file, $directory) {
    $data = $file.OpenBinary()
    $path = Join-Path $directory $file.Name
    progress $path
    [System.IO.File]::WriteAllBytes($path, $data)
}

#Forms folder doesn't need to be copied
$formsDirectory = Join-Path $rootDirectory "Forms"

function Pull($folder, [string]$directory) {
    $directory = Join-Path $directory $folder.Name
    if ($directory -eq $formsDirectory) {
        return
    }
    mkdir $directory | out-null

    $folder.Files | Foreach { Save $_ $directory }

    $folder.Subfolders | Foreach { Pull $_ $directory }
}

Write "Copying files recursively"
Pull $folder $directory

$web.Dispose()

I have tested this script in SharePoint 2007 and 2010. It works. Let me know if you find this useful or have some suggestions.

Daniel Chronlund Cloud Tech Blog

News, tips and thoughts for Microsoft cloud fans

Вула Чăвашла

VulaCV - Чăвашла вулаттаракан сайт

Discovering SharePoint

And going crazy doing it

Bram de Jager - Architect, Speaker, Author

Microsoft 365, SharePoint and Azure

SharePoint Dragons

Nikander & Margriet on SharePoint

Mai Omar Desouki

PFE @ Microsoft

Cameron Dwyer

Office 365, SharePoint, Azure, OnePlace Solutions & Life's Other Little Wonders

paul.tavares

Me and My doings!

Share SharePoint Points !

By Mohit Vashishtha

Jimmy Janlén "Den Scrummande Konsulten"

Erfarenheter, synpunkter och raljerande om Scrum från Jimmy Janlén

Aryan Nava

DevOps, Cloud and Blockchain Consultant

SPJoel

SharePoint for everyone

SharePointRyan

Ryan Dennis is a SharePoint Solution Architect with a passion for SharePoint and PowerShell

SharePoint 2020

The Vision for a Future of Clarity

Aharoni in Unicode

Treacle tarts for great justice

... And All That JS

JavaScript, Web Apps and SharePoint

blksthl

Mostly what I know and share about...