CHUVASH.eu

CHunky Universe of Vigourous Astonishing SHarepoint :)

Tag Archives: PowerShell

SPWebConfigModification

SPWebConfigModification. Some links to start with:

http://panvega.wordpress.com/2009/09/02/using-spwebconfigmodification-within-a-feature-receiver/
http://www.onedotnetway.com/get-name-of-current-executing-assembly-in-c/
http://blogs.devhorizon.com/reza/?p=459
http://ikarstein.wordpress.com/2010/09/02/add-web-config-modification-with-powershell-spwebconfigmodification/
http://msdn.microsoft.com/en-us/library/bb861909.aspx

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
	var webapp = parent as SPWebApplication;
	if (webapp != null)
	{
		var mod1 = GetWebControlsConfigMod();
		webapp.WebConfigModifications.Add(mod1);
		var mod2 = GetConStringConfigMod();
		webapp.WebConfigModifications.Add(mod2);
		SaveChanges(webapp);
	}
	else
	{
		Log.Warning("no modifications to webapp are done");
	}
}

public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
	var webapp = parent as SPWebApplication;
	if (webapp != null)
	{
		var mod = GetWebControlsConfigMod();
		var modsCollection = webapp.WebConfigModifications;
		var modToDelete =
			(from m in modsCollection
			 where m.Value.Equals(mod.Value, StringComparison.InvariantCultureIgnoreCase)
			 select m).FirstOrDefault();
		if (modToDelete != null)
		{
			modsCollection.Remove(modToDelete);
			SaveChanges(webapp);
		}
	}
}
private static void SaveChanges(SPPersistedObject webapp)
{
	var service = webapp.Farm.Services.GetValue();
	service.ApplyWebConfigModifications();
	webapp.Update();
}

private static SPWebConfigModification GetWebControlsConfigMod()
{
	var assembly = System.Reflection.Assembly.GetAssembly(typeof(WebControls.OfficeEditor));
	var ass = assembly.FullName;
	var @namespace = assembly.GetName().Name + ".WebControls";
	var value = string.Format("", ass,
							  @namespace);
	const string path = "configuration/SharePoint/SafeControls";
	var mod = new SPWebConfigModification
	{
		Path = path,
		Name = "JustaName1",
		Sequence = 0,
		Owner = @namespace,
		Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode,
		Value = value
	};
	return mod;
}

private static SPWebConfigModification GetConStringConfigMod()
{
	const string name = "ContosoConString";
	const string conString =
		"Data Source=db.contoso.com;Initial Catalog=contoso_db;Persist Security Info=True;User ID=contoso_Contributor;Password=contoso";
	var mod = new SPWebConfigModification
	  {
		  Name = "JustaName2",
		  Path = "configuration/connectionStrings",
		  Owner = "contoso_connectionstrings",
		  Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode,
		  Value = String.Format("", name, conString)
	  };
	return mod;
}

Powershell:

#ADDING
asnp microsoft.sharepoint.powershell
$url = "http://contoso"
$app = Get-SPWebApplication $url
$name = "ContosoConString";
$conString = "Data Source=db.contoso.com;Initial Catalog=contoso_db;Persist Security Info=True;User ID=contoso_Contributor;Password=contoso";
$mod = new-object Microsoft.SharePoint.Administration.SPWebConfigModification
$mod.Name = "JustName2"
$mod.Path = "configuration/connectionStrings"
$mod.Owner = "User Name"
$mod.Type = 0 #for the enum value "SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode"
$mod.Value = '<add name="{0}" connectionString="{1}" />' -f $name, $conString
$app.WebConfigModifications.Add($mod)
$service = [Microsoft.SharePoint.Administration.SPWebService]::ContentService
$service.ApplyWebConfigModifications()
$app.Update()
#ADDING snapin
asnp microsoft.sharepoint.powershell

$url = "http://contoso"
$app = Get-SPWebApplication $url

#SafeControl
$assembly = "Contoso.SP, Version=1.0.0.0, Culture=neutral, PublicKeyToken=20c0327f8b01d979"
$namespace = "Contoso.SP.WebControls"
$mod = new-object Microsoft.SharePoint.Administration.SPWebConfigModification
$mod.Name = "ContosoSafeControls"
$mod.Path = "configuration/SharePoint/SafeControls"
$mod.Owner = "Contoso"
$mod.Type = 0 #for the enum value "SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode"
$mod.Value = '<SafeControl Assembly="{0}" Namespace="{1}" TypeName="*" Safe="True" />' -f $assembly, $namespace
$app.WebConfigModifications.Add($mod)

#applying changes
$service = [Microsoft.SharePoint.Administration.SPWebService]::ContentService
$service.ApplyWebConfigModifications()
$app.Update()

#REMOVING
asnp microsoft.sharepoint.powershell
$app = Get-SPWebApplication http://contoso
$modCol = $app.WebConfigModifications
$mod = $modCol| Where { $_.Owner.Equals("User Name") }
$modCol.Remove($mod)
$service = [Microsoft.SharePoint.Administration.SPWebService]::ContentService
$service.ApplyWebConfigModifications()
$app.Update()

#if you want to clear all web.config mods associated with the web app:
$modCol = $app.WebConfigModifications
while ($modCol -ne 0) { $modCol.Remove($modCol[0]) }
$service.ApplyWebConfigModifications()
$app.Update()

Allright, how can we apply changes in the whole farm? Ryan Dennis uses $app.Parent.Apply.. Rajkamal says we have to run service.Apply (if it would be in C#). To Get Service we can use generics in PowershellKeith Dahlby writes about SPWebService.ContentService.

Add the first connectionString

I encountered a problem adding the first connection string by this script. It just didn’t work. The solution is to add the parent element “connectionStrings”.

\n and \t in powershell

Want to add some tabs and new lines to your output in Powershell. Well, it works like \n and \t. But there is a little different syntax: `t and `n. Just a tip. An alternative way to add new line is to use [Environment]::NewLine:

$nl = [Environment]::NewLine
$var = "hej" + $nl
Write $var

Add Sharepoint Snap-in if needed

Just include it in your script or function:

if(-not(Get-PSSnapin | 
   Where { $_.Name -eq "Microsoft.SharePoint.PowerShell"})) { 
   Add-PSSnapin Microsoft.SharePoint.PowerShell}

By the way, I found it in PowerShell for Microsoft SharePoint 2010 Administrators by Niklas Goude and Mattias Karlsson.

Powershell for Sharepoint Administrators

UPDATE: I found a better way to check a variable for null: Thomas Maurer. Powershell: check variable for null. It is like in javascript, just put it in the if-statement to test if it exists or not:

if($variable) {} #if exists
if(!$variable) {} #if not exists

So to add sharepoint snapin if needed, just run this:

$snapin = Get-PSSnapin | ? { $_.Name -eq "Microsoft.SharePoint.PowerShell"}
if(!$snapin) { 
   asnp Microsoft.SharePoint.PowerShell
}

Another example for checking if something exists, is to try get a site and remove it:

$url = "http://dev"
$site = get-spsite | ? { $_.Url -eq $url }
if($site) {
	remove-spsite $url -confirm:$false
}

Add global navigation links in Powershell and Feature Receiver

I think, powershell is the best way to do configurations you have to do once. Adding some links to global (top) navigation is one of them:

asnp microsoft.sharepoint.powershell
$w = get-spweb http://takana
$l = New-Object Microsoft.SharePoint.Navigation.SPNavigationNode("Smells like team spirit", "/pages/teamspirit.aspx")
$w.Navigation.TopNavigationBar.AddAsLast($l)
Feature receiver

The alternative is to create a web scoped feature and provide properties:

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
    var web = properties.Feature.Parent as SPWeb;
    var prop = properties.Feature.Properties["MyGlobalLinks"];
    var links = prop.Value.Split(new[] { ";#" },
               StringSplitOptions.RemoveEmptyEntries);
    foreach (var item in links)
    {
        var newLink = item.Split(new[] { ";" },
                            StringSplitOptions.RemoveEmptyEntries);
        var newMenuItem =
                new SPNavigationNode(newLink[0], newLink[1]);
        web.Navigation.TopNavigationBar.AddAsLast(newMenuItem);
    }
}

This feature can be prefereably hidden. The properties are passed in onet:

<!--Meglerfront: Page Navigation-->
<Feature ID="7829235a-ffb3-4ddf-0b5b-2a1d79668aa5">
  <Properties xmlns="http://schemas.microsoft.com/sharepoint/">
    <Property Key="MyGlobalLinks"
     Value="Salam;/$Resources:cmscore,List_Pages_UrlName;/salam.aspx;#Ciper;/$Resources:cmscore,List_Pages_UrlName;/ciper.aspx" />
  </Properties>
</Feature>

In the example no error handling is provided for the sake of brevity.

NavBarLink

I found even a third way to add links to global navigation: NavBarLink

<NavBars>
<NavBar Name="$Resources:core,category_Top;"
    Separator="&amp;nbsp;&amp;nbsp;&amp;nbsp;"
    Body="&lt;a ID='onettopnavbar#LABEL_ID#' href='#URL#' accesskey='J'&gt;#LABEL#&lt;/a&gt;"
    ID="1002">
  <NavBarLink Name="Hello" Url="/sider/Hello.aspx"/>
  <NavBarLink Name="Hello2" Url="javascript:SayHello();"/>
</NavBar>
</NavBars>

It is much simpler, as simple as unbelievable :). Are there some problems with NavBarLinks?

Edit: I found one shortcoming with NavBarLink: you can’t use resources from cmscore like $Resources:cmscore,List_Pages_UrlName;. To solve we can create a copy of this string in our custom resource file: $Resources:Takana,List_Pages_UrlName;.

Batch remove

To add items to a list in bulk, or remove them in bulk. Well to do that you can use SPLinq, Server Object Model and … web.ProcessBatchData, which is the most effective.

I did an experiment today. I created 1000 tasks in my task list three times and removed all items in three different ways and took time.

First I put 1000 items with ajax and listdata.svc:

function pad(n) {
   if (n >= 10000) return n;
   if (n >= 1000) return '0' + n;
   if (n >= 100) return '00' + n;
   if (n >= 10) return '000' + n;
   return '0000' + n;
 }
var s;
var counter = 0;
var title = "task "
function foo() {
   counter++;
   if (counter > 10000) {
      window.clearInterval(s);
   }
   else {
      var value = {};
      value.title = title + pad(counter);
      createNewTask(value);
   }
}
s = setInterval(foo, 200);

Then I ran three different scenarios. Here is the resut for VMWare machine Windows Server 2008 R2, 4GB RAM, SharePoint 2010 SP1:

1000 items 10 000 items 20 000 items
Batch 00h:00m:28s.950ms (29s) 00h:04m:20s.730ms (261s) 00h:08m:35s.260ms (515s)
Object Model 00h:01m:37s.860ms (98s) 00h:16m:40s.770ms (1001s) 00h:33m:50s.250ms (2030s)
SPLinq 00h:02m:24s.070ms (144s) 02h:17m:02s.570ms (8223s) 11h:51m:08s.130ms (42668s)

This result confirms another comparision. See even advantages and disadvantages of linq2sp vs caml.

The time includes even the instantiation of the SPSite and SPWeb objects and getting of task ids to remove, this to get a fair comparision with SPLinq, where this instantiation is implicit (within the context).

Average time for removing one list item:
1000 items 10 000 items 20 000 items
Batch 29.0ms 26.2ms 25.8ms
Object Model 97.9ms 100.1ms 101.5ms
SPLinq 144.1ms 822.3ms 2133.4ms

Some curious facts:
1. SPLinq method left one list item after removing 10 000 batch (task 08787) and three items while removing 20 000 batch (task 07550, task 12042, task 19663). Why?

2. I opened the list sometimes and I found that deleting of items took very long time in the beginning, and then it became faster and faster. I suppose the whole data context was saved after every submission. I am wondering if it would  be different if I’d set ObjectTrackingEnabled to false, which is true by default.

See the whole blog entry for the code I ran to compare these three ways to remove list items.

Read more of this post

Powershell scripts for AD

A tip for all who want to administer AD with powershell: Idera Powershell scripts. Just sign up and get the free scripts for AD, SQL, Exchange and Sharepoint.

I personally prefer to user modules, so I change the file extension from ps1 to psm1 and then I can use import functions as modules. Here is a simple example for creating for domain users:

import-module .\New-IADUser1.psm1
function Add-User($name) {
    New-IADUser -Name $name 
         -sAMAccountname $name 
         -ParentContainer 'CN=Users, DC=contoso, DC=com' 
         -Password 'SvenskaAkademien1786' 
         -EnableAccount -PasswordNeverExpires
}
Add-User "user01"
Add-User "user02"
Add-User "user03"
Add-User "user04"
update 2012-03-15: nice script from Ryan

Ryan Dennis has created a very handy script for creating random users.

In PowerShell v3.0 there is a cmdlet for creating users: New-ADUser. So the function above can be rewritten like that:

Import-Module ActiveDirectory -ErrorAction SilentlyContinue
function Add-User($name) {
    $password = ConvertTo-SecureString 'SvenskaAkademien1786' -AsPlainText -Force
    New-ADUser -Name $name 
         -sAMAccountname $name 
         -Path 'CN=Users, DC=contoso, DC=com' 
         -AccountPassword $password
         -Enabled $true
         -PasswordNeverExpires $true
}
Add-User "user01"
Add-User "user02"
Add-User "user03"
Add-User "user04"

Uninstall custom features in a batch

A funny powershell command I came upon today together with my colleague. Remove all your custom features (which start with something, say contoso):

Get-SPFeature 
       | Where { $_.DisplayName.StartsWith("Contoso.") } 
       | ForEach { Uninstall-SPFeature $_.Id -confirm:0 -force }
Have fun!

Sharepoint Warmup Script

It is useful to warm up a site after app pool recycling or after a site creation in development environments. I found a very simple script which I made even simpler:

$url = "http://takana"
$wc = new-object net.webclient
$wc.credentials = [System.Net.CredentialCache]::DefaultCredentials
$wc.DownloadString($url) | out-null
$wc.Dispose()

For more sophisticated warmups Wahid Salemi provided an interisting script to warm up your Sharepoint.

By the way. Let us save it as a powershell function. Take a look at sharepointryan’s functions. Let’s create a proper function of that:

function WarmUp-Site {
<#
.Synopsis
	Use this PowerShell script warm up a site.
.Description
	This PowerShell script uses net.webclient class to download the page and trigger warmup.
.Example
        WarmUp-Site -url http://intranet
	This example warms up http://intranet site.
.Notes
	Name: WarmUp-Site
	Author: Anatoly Mironov
	Last Edit: 2012-01-25
	Keywords: Warmup, Site
.Link
	https://sharepointkunskap.wordpress.com
.Inputs
	None
.Outputs
	None
#Requires -Version 2.0
#>
[CmdletBinding()]
Param(
[string]$url=(Read-Host "Please provide a site url (Examples: http://intranet)")
)
	$wc = new-object net.webclient
	$wc.credentials = [System.Net.CredentialCache]::DefaultCredentials
	$wc.DownloadString($url) | out-null
	$wc.Dispose()
}

Change CA port number

In order to change port number for the Central Administration site, run this cmdlet:

Set-SPCentralAdministration -Port 1337

You can set any number between 1023 and 32767 except 443.

Get role assignments of a web or a list

In Powershell you can easily get the permissions in a web or in a list:

$web = get-spweb http://contoso.com
$web.Groups | select Name, Roles > .\Desktop\webgroups.txt
$list = $web.Lists.TryGetList("Assets");
$list.RoleAssignments | select Member, RoleDefinitionBindings > .\Desktop\assets-roleassignements.txt

To get all users in all groups run:

$web.Groups | Foreach { Write $_.Name; Write "-------------";  $_.Users | Select Name; Write ""; Write "" }
Вула Чăвашла

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

Discovering SharePoint

And going crazy doing it

Bram de Jager - Coder, Speaker, Author

Office 365, SharePoint and Azure

SharePoint Dragons

Nikander & Margriet on SharePoint

Paul J. Swider - RealActivity

RealActivity is a specialized Microsoft healthcare services and solution advisory firm.

Cameron Dwyer | Office 365, SharePoint, Outlook, OnePlace Solutions

Office 365, SharePoint, 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

| Blockchain | Serverless Architecture | Microservices Architecture | DevOps | AWS Lambda | Teraform |

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 about SharePoint - CommunicoCuspis