Below you will find pages that utilize the taxonomy term “Powershell”
Show Path Column in SharePoint
PnP.PowerShell is just the tool you need to show the Path column in a SharePoint document library view. Scroll down to see the script, or read on to learn more.
An introduction
Do you still have folders in SharePoint? Well, you are not alone. Remember the old dream of relying on metadata only? Forget it! As a matter of fact, folders are still a popular way of organizing files in SharePoint. When not overused, they provide “metadata” by itself, metadata that works even in synced folders, in archive scenarios, works best with Teams etc.
Automate Creation of Git Repos Using Azure DevOps API
Today I got a question: how can we precreate 50 git repositories in an Azure DevOps Project? I started to learn about the API in Azure DevOps and I found it very interesting. With the API you can script and automate administration of projects, repositores, pull requests etc. To keep this blog post simple and digestable I would like to focus on the intitial request - creating git repositories by code.
A powershell script for activating an eligible role assignment in Azure AD
Recently my role assignments in Azure AD were switched from permanent to eligible ones. This is part of PIM - Privileged Identity Management, you can read more about it on MS Docs:
To activate your eligible assignment you can use Azure Portal, Graph API, and PowerShell. The activation in the portal and Graph API is described on MS Docs:
Sites.Selected and Governance
The new permission in Graph API - Sites.Selected - is a step in the right direction. Since long we have been looking for ways of scoping the accesses to live up to the least privilege principle. It was either nothing or everything. I have tried out the new Sites.Selected permission and here are my findings.
First of all, if you haven’t heard about Sites.Selected, please visit these pages to find out more. I am skipping the introduction, since there are already good resources on that out there.
Smarter way of loading SharePoint CSOM dll in PowerShell
Have you also got a legacy powershell script that loads SharePoint dlls and runs CSOM code directly? It’s quite easy to convert to PnP PowerShell. But if you run out of time and just need to execute the script, then I have a quick tip for you.
First of all, a CSOM script can be recognized by Add-Type commands (or Import-Module) plus the SharePoint dll paths.
Loading the dll the old way.
A cost effective way of running legacy scripts in the cloud
Have you also got some old huge scripts that run on a server locally? Have you also considered moving them to the cloud? Here comes an idea of how to do it quickly and easy.
In my case I have some older powershell scripts that are harder to convert to serverless applications:
- They use MSOnline module in PowerShell, hence they require rewriting to AzureAD before using them in an Azure Function
- They take around 15 minutes to complete, Azure Functions Consumption Plan is limited to 10 minutes. Of course I can split them in several parts, but I am looking for an easy way right now, I have to postpone refactoring because I am not sure if there is a real need for this script solution.
- They process a lot of data and consume more that 400 MB memory which makes it crash when I put it in a Azure Automation Runbook.
Well, maybe a Windows Server VM in Azure is the only way? While recently setting up a minecraft server and following a blog post that proposes auto shutdown and logic apps to start the server, I came up with an idea to use exactly the same approach to make it as cost effective as possible.
Demote News in SharePoint Online
In case you published a news in SharePoint Online and you now want to “downgrade” it to a regular page, I have a solution for you.
The reasons why you would like to demote a News might vary:
- You publish an important message, perhaps a note about an operational disturbance. It might not relevant anymore, but you still want to keep the page in case someone wants to access the information.
- You accidentally create a page as a news.
- …
Add a security group as hubbers using PowerShell
Today I needed to add a security group to “People who can associate sites with this hub” through PowerShell. Here is quick how-to. I usually say “hubbers” instead of the long “People who….”. By the way, if you want to know what prerequisites there are for being a hubber, read my other blog post
An example of how to add a security group is missing in the MS Docs:
Setting up a HelloWorld Azure Alert
Azure Alerts are awesome for monitoring of solutions in Azure. If you are about to set up your first Alert Rules in Azure, then it’s a guide for you. Configuring alert rules can be quite intimidating at first, with all the options, metrics, evaluation times, etc.
Here is a very very simple setup that can serve as a teaser and help you get started with the Azure Alerts.
Is an M365 Group a Yammer Community
Nowadays a Yammer Community gets a corresponding Microsoft 365 Group (Office 365 Group, Unified Group). In your work as an SPO Admin, you might need to differentiate “ordinary” Modern Team Sites from those ones that were created for a Yammer Community.
They both have GROUP#0 as Template. On the actual SPO Site object, there is nothing that you can use to differentiate those. Neither you can use the Office 365 Group information. But there is a way: if you connect to Exchange Online and get the group from there, then there is something useful.
Estimated Completion in Write-Progress in PowerShell
Have you also got many sites in your tenant? Write-Progress is the bare minimum in a script that goes through all sites. But there is also another nice way to make easier to see the progress - estimated completion time.
Although the idea comes from another blog post (My life is a message), I thought it could be worth sharing it again, especially in the cloud context.
Here is a bit simplified scenario: Getting information for every site. The status message in Write-Progress contains also the estimated completion time.
Optimizing lookups in PowerShell
Have you had a PowerShell script that contains two bigger arrays and you wanted merge the information. It can become quite slow if you need to search for every item from array A through all items in array B. The solution is called a HashTable! It might be not an advanced tip for some, but I was really glad to see a huge improvement, so I decided to share it as a post.
Get totals from a list view using PowerShell
Today I will share a short script for getting totals from a list view in SharePoint. Imagine this scenario: you have set up a list view with totals and you want get the totals every day for statistics or some other reasons. Instead of getting all items, and/or fiddling around with CamlQueries, there is a better and quicker way - List.RenderListData. This combined with a tip from Piyush K Singhs blog post Get Aggregate Values… I came up with an idea to read the ViewXml from an existing view and retrieve the totals (in my case Count and Sum). Enough talking, let’s take a look at the code:
My PowerShell Profile
It has been a while I last worked with PowerShell. I had my custom profile where I had my own prompt and some other customizations. Now I cannot find it anymore. I’ll start with the new one and I am saving it on my blog, so it will be easier to find in future: [code language=“powershell”] Function Prompt { $PromptData=“PS $($executionContext.SessionState.Path.CurrentLocation)$(’>’ * ($nestedPromptLevel + 1)) " $host.ui.RawUI.WindowTitle=$PromptData +’-’+(Get-Date).tostring() # .Link# http://go.microsoft.com/fwlink/?LinkID=225750 # .ExternalHelp System.Management.Automation.dll-help.xml } [/code] The prompt function comes from the scripting guy blog. To customize your profile, just open it in a text editor (in my case: code) [code language=“powershell”] code $profile [/code] Update 2018-04-10 You can also include these lines: [code language=“powershell”] $path1 = “C:\Program Files\Common Files\microsoft shared\Web Server Extensions\” $path2 = “15” Add-Type -Path “$path1\$path2\ISAPI\Microsoft.SharePoint.Client.dll” Add-Type -Path “$path1\$path2\ISAPI\Microsoft.SharePoint.Client.Runtime.dll” [/code] VS Code Now we can run VS Code to create ps1 scripts and run selections as we did it in PowerShell ISE.
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: [source] http://<site_url>/_vti_bin/owssvr.dll?Cmd=Display&List=&View=&Query=*&XMLDATA=TRUE [/source] To automate this I have written a PowerShell function. All the details are in the comments: [source language=“PowerShell”] 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) } [/source]
Showing Birthdays and Job Anniversaries in the Newsfeed
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:
[source language=“PowerShell”] $job = Get-SPTimerJob | ? { $_.TypeName -like “*.UserProfileChangeJob” } $job.GenerateAnniversaries = $true $job.Schedule = [Microsoft.SharePoint.SPSchedule]::FromString(“hourly between 55 and 55”) $job.Update() [/source]
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:
The Git Shell will open a PowerShell window and execute shell.ps1 from the Github directory:
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:
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.
[slideshare id=37316916&doc=sharepoint-140724063012-phpapp01&w=600]
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 [code language=“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 } [/code] This solution uses ranges, dynamic objects (PSObject), nested for loops, implicit returns and advanced filtering. All that is is out-of-the-box PowerShell.
Debugging "What's happening" in Communities
Recently an issue was reported about count mismatches in SharePoint 2013 Communities. The number of replies in category tiles sometimes is different compared to the community stats in the web part called “What’s happening”. The actual number of replies is 1 in the figure below. The user who has reported has tried to add, update and delete discussions and replies. I have invested some time debugging this issue. It would be pity to not share my findings. Well the first thing to do was to determine the type name for the “What’s happening” web part. To do so just edit the page and export the web part. In the exported .webpart file I saw that the type was Microsoft.SharePoint.Portal.WebControls.DashboardWebPart. With that knowledge it is time to open ILSpy, an awesome and free(!) assembly browser and decompiler. Load the “Microsoft.SharePoint.Portal” assembly from GAC into ILSpy. Then use F3 to search for DashboardWebPart: The number of replies is retrieved from SPWeb.AllProperties: If the Property Bag does not contain it, it gets the number of replies from the list. The formula is as follows: [code language=“csharp”] list.ItemCount - list.RootFolder.ItemCount [/code] It means that it gets the number of both discussions and replies: ItemCount of Discusssions List. The number of Discussions is determined by the ItemCount in the RootFolder of the Discussions List. Discussions are List Items in the RootFolder (num2 in the figure below). Replies are saved in the subfolders, every discussion gets an own folder. The number of all replies are num3 in the figure below. After checking the web properties I could see that the number of replies there were wrong: 2. The next step was to determine where and when the Web Properties are updated. The first guess every SharePoint Developer has in such cases is an EventReceiver. Here are all EventReceivers connected to the Discussions List: [code language=“powershell”] $list.EventReceivers | select class, Type, Synchronization | Out-GridView [/code] Allright, CommunityEventReceiver then: Found where the actual update happens: CommunityUtils.UpdateWebIndexedPropertyBag The method is used in DiscussionListCommunityEventHandler.HandleEvent There is a flag, flag5 that is used to determine if the Web Properties should be updated: But the flag5 is not true on Delete operations in some code flows: That’s it. So deleting a reply will not have any effect on “What’s happening”. But adding a new discussion will also update the stats: To summarize the debug session, there is an issue in the OOB code that misses to update community stats when deleting a discussion or a reply. Adding a new discussion, or a reply will synchronize the stats.
PowerShell: Migrate field choices to a termset
In my current project we are migrating a custom sharepoint solution from SharePoint 2010 to SharePoint 2013. One of the improvements is that we migrate custom field choices to Managed Metadata. Choice Fields were not intended to be so many. So now it is time to convert them to metadata terms. I have written a PowerShell script which copies all the choices from a field to a termset. The script uses Client Side Object Model (CSOM) to get the choice values and it uses Server Object Model to write data to the termset. [sourcecode language=“PowerShell”] <# .Synopsis Use MigrateChoices.ps1 to migrate choices from a field to managed metadata. The source can be a contenttype field from SharePoint 2010 or from SharePoint 2013. .Description This script uses client object model to get the list items from the old environment. Then it uses the Server Object Model to create new terms and termsets (if needed) in the new environment. This script doesn’t override anything. The reason why we use it, is that importing feature isnt easy It creates a new, instead of adding new terms to old ones. It is very hard to create an csv file for that purpose. .Example MigrateChoices.ps1 -Source http://sp2010.contoso.com -Target https://sp2013.contoso.com .Notes Name: MigrateChoices.ps1 Author: Anatoly Mironov Last Edit: 2013-09-04 Keywords: CSOM, Field, FieldChoice, Metadata, Termset .Links http://chuvash.eu .Inputs The script takes Source parameter, it is url for the root web in the Source Site Collection The script takes Target parameter, it is url for the root web in the Target Site Collection .Outputs None #Requires -Version 2.0 #> [CmdletBinding()] Param( [Parameter(Mandatory=$true)][System.String]$Source = $(Read-Host -prompt “Source site Url”), [Parameter(Mandatory=$true)][System.String]$Target = $(Read-Host -prompt “Target site Url”), [Parameter(Mandatory=$false)][System.String]$TermGroupName = “My group”, [Parameter(Mandatory=$false)][System.String]$TermGroupId, [Parameter(Mandatory=$false)][System.String]$TermSetName = “My termset”, [Parameter(Mandatory=$false)][System.String]$TermSetId, [Parameter(Mandatory=$false)][System.String]$FieldName = $(Read-Host -prompt “Field Choice Name”) ) if(-not(gsnp | ? { $_.Name -eq “Microsoft.SharePoint.PowerShell”})) { asnp Microsoft.SharePoint.PowerShell } # try to instantiate the target site, if it fails, then it does not run in the right environment $targetSite = get-spsite $Target # predefined termset guids: $guids = @{ “group” = if ($TermGroupId) {New-Object system.guid $TermGroupId } else { [system.guid]::NewGuid() } “termset” = if ($TermSetId) {New-Object system.guid $TermSetId } else { [system.guid]::NewGuid() } } function GetChoices() { $ctx = New-Object Microsoft.SharePoint.Client.ClientContext($Source) $field = $ctx.Web.Fields.GetByInternalNameOrTitle($FieldName) $ctx.Load($field) $ctx.ExecuteQuery() return ([xml]$field.SchemaXml).Field.Choices.Choice } function New-Term { [CmdletBinding()] Param( [Parameter(Mandatory=$true)][Microsoft.SharePoint.Taxonomy.TermSetItem]$parent, [Parameter(Mandatory=$true)][System.String]$name ) if (!$parent) { throw new-object System.ArgumentException $parent } if (!$name) { throw new-object System.ArgumentException $name } $term = $parent[$name] if (!$term) { $parent.CreateTerm($name, 1033) | out-null } } function CreateTerms() { $taxSession = Get-SPTaxonomySession -Site $targetSite $termStore = $taxSession.DefaultSiteCollectionTermStore $group = $termstore.Groups[$TermGroupName] if (!$group) { $group = $termStore.CreateGroup($TermGroupName, $guids.group) } $termSet = $group.TermSets[$TermsetName] if (!$termset) { $termset = $group.CreateTermSet($SecurityClassificationTermSetName, $guids.termset, 1033) } GetChoices | % { New-Term $termSet $_ } $termStore.CommitAll() $targetSite.Dispose() write-host -ForegroundColor Green “The term sets have been created” } CreateTerms [/sourcecode]
PowerShell: Get version and ProductId from an .app package
In my project I deploy some apps directly through the ObjectModel directly with PowerShell. The apps are built with TFS I have a script that installs or updates apps if there is a new version of the app. Previously I used Import-SPAppPackage to compare the version and productid with an existing app instance, but often I get this error:
The provided App differs from another App with the same version and product ID.
Count lines of code with PowerShell
Today I got a question:
How many lines of code are there in our SharePoint solution?
After a little search, I found that PowerShell is really a nice tool to count lines of code:
I wanted to count lines for different types of code:
- Code Behind written in C#, the files have .cs file extension
- JavaScript code (except jQuery, angular or knockout frameworks)
- PowerShell files (.ps1 and psm1)
- Xml files (all the SharePoint .xml files)
Here is the powershell code that counts lines of code: [code language=“powershell”] # go to the solution folder cd #count lines in .cs files ls -include *.cs -recurse | select-string . | measure | select count #count lines in our .js files ls -include *.js -recurse ` -exclude *min.js, jquery*, _*, jsrender*, CamlBuilder*, knockout* ` | select-string . ` | measure ` | select Count #count lines in our powershell scripts ls -include *.xml -recurse | select-string . | measure | select count #count lines in our powershell scripts ls -include *.ps1, *.psm1 -recurse | select-string . | measure | select count [/code] Just a curious fact, I can’t tell you how many lines of code we have in our solution, but I can reveal the proportions. If I used the flexible box model in css3, it would look like this: There are as many lines of code written in javascript as it is in C#. The main reason that for the big js code base are the SharePoint hosted apps. The PowerShell scripts are as big the javascript code base. Xml files are 4 times bigger than C# code, and it is even bigger than the sum of all lines of code written in C#, JavaScript and PowerShell. It isn’t strange that xml is dominating, almost everything in SharePoint is defined in xml. Fortunately, there are less cases where you have to write raw xml in Visual Studio 2012/2013 and SharePoint 2013. How does it look in your project? What language is dominating in your SharePoint project?
scriptcs and SharePoint. How SharePoint can benefit?
Last Saturday I attended Leetspeak. Among many awesome speeches and presentations I discovered scriptcs. scriptcs lets you write C# code directly in the console, or execute scripts written with just your favourite editor. Please see more about it on the site. What I thought during Justin Rusbatch’s session at Leetspeak:
Can we use scriptcs in SharePoint?
Technically there is no limitations in SharePoint for scriptcs. Any .NET code can be registered, imported and invoked in a console or in a standalone script. Here is the simple code for instantiating a site collection and disposing it: [code language=“csharp”] #r Microsoft.SharePoint; using Microsoft.SharePoint; var site = new SPSite(“http://dev”); site.Url site.Dispose(); [/code] The code above does not do anything, it is just there to demonstrate how you can register the SharePoint assembly (“Microsoft.SharePoint”) and import it into the script: [code language=“csharp”] using Microsoft.SharePoint; [/code] The example shows even that you in scriptcs no longer need the necessary “boilerplate” (compared to a console application): namespace, Program, Main()… You can just directly write your code. The rest is the same as in a C# application. The code samples for scriptcs can be any code written in C# for SharePoint, code from custom console applications, from feature receivers, you name it. So my next question is:
The CDN concept in SharePoint
How many instances of jquery are there in your SharePoint farm? [sourcecode language=“powershell”] Get-SPWebApplication http://dev ` | Select -Expand Sites ` | Select -Expand AllWebs ` | Select -Expand Lists ` | Select -Expand Items ` | ? { $_.Url -match “jquery.*.js” } ` | select Name, Url [/sourcecode] 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:
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: [sourcecode language=“PowerShell”] sp AutoConfigUrl “http://proxy.contoso.com” ` -Path “HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings” [/sourcecode] By the way sp
is just alias for Set-ItemProperty cmdlet: This corresponds these settings in IE (Tools - Internet Options - Connections - Lan Settings): It can be useful if you have want to automate this.
A quick guide to configuring the Loopback check
Great tutorial how to configure the loopback check on a dev machine. Exactly what I needed for a month ago. Pity that this article came after that. :-) Here is the command to disable it completeley:
\# Disable Loopback check http://support.microsoft.com/kb/896861 #
New-ItemProperty HKLM:\\System\\CurrentControlSet\\Control\\Lsa -Name "DisableLoopbackCheck" -Value "1" -PropertyType dword
AutoSPInstaller: error while stopping the default web site in IIS
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: [sourcecode language=“powershell”] $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)[/sourcecode] becomes this code (the lines in try and catch are identical): [sourcecode language=“powershell”] 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 }[/sourcecode] 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.
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:
Run web.config-dependant code in PowerShell
PowerShell is a great tool. It helps in SharePoint administration and tasks automation. Today I needed to provision a webpart on many similar pages. This third-party webpart’s constructor instantiates a dataaccess service and uses a connectionstring which is stored in the web.config file. So the webpart creation failed until I found a way to load the configuration into powershell. First you can create a simple file powershell.exe.config
, put it into $pshome
(C:\Windows\System32\WindowsPowerShell\v1.0). In that file you can specify the connectionstring in the same way like in the web.config (or app.config). But it is not secure: the connectionstring can be changed in the future, and you really don’t want to copy your connectionstrings around. So there is a better way: Check out Ohad Israeli’s blog post about how a configuration file can be bound dynamically in a .net assembly: Binding to a custom App.Config file. In PowerShell you can do the same, all we need is to modify the syntax: StackOverflow: Powershell Calling .NET Assembly that uses App.config:
Create SPGroup in PowerShell
Thanks to Ryan for sharing powershell functions. I used New-SPGroup which I altered. Now You can define which permissions will be given to the new group. You can even create groups without default users. Here it comes:
function New-SPGroup {
<#
.Synopsis
Use New-SPGroup to create a SharePoint Group.
.Description
This function uses the Add() method of a SharePoint RoleAssignments property in an SPWeb to create a SharePoint Group.
.Example
New-SPGroup -Web http://intranet -GroupName "Test Group" -OwnerName DOMAIN\\User -MemberName DOMAIN\\User2 -Description "My Group" -Role "Read"
This example creates a group called "Test Group" in the http://intranet site, with a description of "My Group". The owner is DOMAIN\\User and the first member of the group is DOMAIN\\User2 and adds "Limited Access".
C:\\PS>New-SPGroup -Web http://intranet -GroupName "Test Group" -OwnerName DOMAIN\\User -MemberName DOMAIN\\User2 -Description "My Group" -Role "Read"
This example creates a group called "Test Group" in the http://intranet site, with a description of "My Group". The owner is DOMAIN\\User and the first member of the group is DOMAIN\\User2 and adds "Read" access.
Pay attention to the role definition names. They must be provided in the language of your site.
.Notes
Name: New-SPGroup
Author: Ryan Dennis, Anatoly Mironov
Last Edit: 2012-11-05
Keywords: New-SPGroup, spgroup, permissions
.Link
http://www.sharepointryan.com
http://twitter.com/SharePointRyan
https://sharepointkunskap.wordpress.com
.Inputs
None
.Outputs
None
#Requires -Version 2.0
#>
\[CmdletBinding()\]
Param(
\[Microsoft.SharePoint.PowerShell.SPWebPipeBind\]$Web,
\[string\]$GroupName,
\[string\]$OwnerName,
\[string\]$MemberName,
\[string\]$Role,
\[string\]$Description
)
$SPWeb = $Web.Read()
if ($SPWeb.SiteGroups\[$GroupName\] -ne $null){
throw "Group $GroupName already exists!"
}
if ($Role) {
$roleDefinition = $SPWeb.RoleDefinitions\[$Role\]
if (!$roleDefinition) {
throw "Role Definition $Role doesn't exist!"
}
}
if ($SPWeb.Site.WebApplication.UseClaimsAuthentication){
$op = New-SPClaimsPrincipal $OwnerName -IdentityType WindowsSamAccountName
$owner = $SPWeb | Get-SPUser $op
if ($MemberName) {
$mp = New-SPClaimsPrincipal $MemberName -IdentityType WindowsSamAccountName
$member = $SPWeb | Get-SPUser $mp
}
}
else {
$owner = $SPWeb | Get-SPUser $OwnerName
if ($MemberName) {
$member = $SPWeb | Get-SPUser $MemberName
}
}
$SPWeb.SiteGroups.Add($GroupName, $owner, $member, $Description)
$SPGroup = $SPWeb.SiteGroups\[$GroupName\]
$roleAssignment = new-object Microsoft.SharePoint.SPRoleAssignment($SPGroup)
if ($Role) {
$roleAssignment.RoleDefinitionBindings.Add($roleDefinition)
}
$SPWeb.RoleAssignments.Add($roleAssignment)
$SPWeb.Dispose()
return $SPGroup
}
Creating custom powershell cmdlet
Why
I need to to activate a feature in PowerShell and specify some properties. Simple? Yes. Possible? No. In the default Enable-SPFeature cmdlet you can’t specify any properties:
Enable-SPFeature –Identity "b5eef7d1-f46f-44d1-b53e-410f62032846" -URL http://dev
We can of course easily add properties when activating features in onet.xml:
<!-- Publishing Resources -->
<Feature ID="AEBC918D-B20F-4a11-A1DB-9ED84D79C87E">
<Properties xmlns="http://schemas.microsoft.com/sharepoint/">
<Property Key="AllowRss" Value="false" />
<Property Key="SimplePublishing" Value="false" />
</Properties>
</Feature>
So I went to SharePoint StackExchange and asked the question. Then I realized: the standard Sharepoin API doesn’t support this neither. The methods of SPFeatureCollection which have SPFeatureProperties as parameter are internal. So the only way is to use Reflection like Hristo Pavlov (2008) and Yaroslav Pentsarsky (2010) suggest. So why not to try to create a cmdlet?
Out-Gridview in PowerShell
Did you know that we can pipe the output from PowerShell into a graphical GridView? I have used PowerShell for one year and only now I discovered this nice feature. You can add filter criteria, you can filter by typing in a textbox:
Other useful output cmdlets
- out-file
- out-clip
- out-null
Run powershell remotely
To run powershell remotely is really easy. First enable it on the machine which will receive the remote commands:
Enable-PSRemoting
Then go to another machine and connect to your host:
$cred = Get-Credential
Enter-PSSession -Computername dev -Credential $cred
If you want to know more about powershell remoting, I recommend “A layman’s guide…”. See even a detailed example on poshcode.
Access User Profile Properties from Powershell
To use only SPUser objects isn’t always sufficient. To get other properties we have to retrieve user profiles. Giles Hamson gives an example how to get and how to update user profile properties with powershell. Here is an example how to get all work phones:
$url = "http://intranet/"
$site = Get-SPSite $url
$context = Get-SPServiceContext $site
$profileManager = New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($context)
$profiles = $profileManager.GetEnumerator()
while ($profiles.MoveNext()) {
$userProfile = $profiles.Current
$name = $userProfile.DisplayName
$phone = $userProfile\["WorkPhone"\]
$line = '{0};{1}' -f $name, $phone
write $line
}
If you are not sure what properties are called, see the whole list by typing:
Adding organizational units to AD through powershell
Want to create some organizational structure in AD, I suppose it is specifically useful in a development environment, well the best solution is powershell then. Mastering Powershell by and Powershell.nu by Niklas Goude provide examples how to do this.
$domain = \[ADSI\]""
$ou = $domain.Create("organizationalUnit", "OU=Administration")
$ou.SetInfo()
```Be sure you write "organizationalUnit" in lower case. Otherwise you'll get "Exception calling "SetInfo" with "0" argument(s): "The specified directory service attribute or value does not exist" when you invoke **$ou.setinfo()**. If you want to create an OU under another OU, just create $domain and specify the location: \[code language="powershell"\] $domain = \[ADSI\]"OU=Administration, dc=takana, dc=local" $company = $domain.Create("organizationalUnit", "OU=Accounting") $company.SetInfo()</pre> To save some other properties: <pre>$ou.put("Description", "this is a dummy ou") $ou.SetInfo() \[/code\]
#### Update 2013-12-10
In PowerShell V3 you have a built-in cmdlet for doing that once you add the Active Directory role in your server. It simple as that: \[code language="powershell"\] New-ADOrganizationalUnit "Accounting" -Path "dc=takana, dc=local" \[/code\]
Install a custom timer job in Powershell
First we have to create a class for our timer job which inherits SPTimerJobDefinition, build it and deploy it.
public class TakanaTimer : SPJobDefinition
{
public TakanaTimer(){}
public TakanaTimer(string jobName, SPService service,
SPServer server, SPJobLockType targetType)
: base(jobName, service, server, targetType) { }
public TakanaTimer(string jobName, SPWebApplication webapp)
: base(jobName, webapp, null, SPJobLockType.ContentDatabase)
{
Title = jobName;
}
public override void Execute(Guid contentDbId)
{
Log.Info("Running Takana Timer");
}
}
There is a powershell example for this, but it has not been updated since MOSS.
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 = ‘’ -f $name, $conString $app.WebConfigModifications.Add($mod) $service = [Microsoft.SharePoint.Administration.SPWebService]::ContentService $service.ApplyWebConfigModifications() $app.Update() #ADDING snapin asnp microsoft.sharepoint.powershell
\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:
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:
NavBarLink
I found even a third way to add links to global navigation: NavBarLink
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:
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: [code language=“powershell”] 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” [/code]
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!
Configure User Profile Service Application
Today I have struggled with User Profile Service Application. I should have followed this awesome tutorial by ShareponitGeorge. And many thanks to my friend David for the great assistance! One important thing to beware about: Forefront Identity Manager Service must be running. Otherwise you don’t see the existing synchronization connections and you can’t add new connections. You can ensure that this service is running by running services.msc (just press Windows button and write services). Or you can do in powershell:
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:
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 "" }
pause in Powershell
Om man högerklickar och väljer “Run With Powershell”, är det bra om fönstret inte försvinner… Det hade varit bra med en funktion som pause… Här kommer väl till pass en egen pause.:
function Pause ($Message="Press any key to continue...")
{
Write-Host -NoNewLine $Message
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
Write-Host ""
}
powershell.exe -Command
man kan skapa en .bat-fil med olika powershell-anrop:
powershell.exe -Command "& {.\\Script1.ps1}"
Flaggor i powershellfunktioner
Har länge letat efter möjligheten att skriva funktioner med egna flaggor på ett enkelt sätt. “Flaggor” (flags) är namngivna parametrar. Följande kommando har flaggor: -Identity, -WebApplication och -GACDeployment.
Install-SPSolution -Identity contoso.portal.wsp -WebApplication http://contoso -GACDeployment
```Låt oss titta på ett gammalt exempel:
function hello($firstname, $lastname) { Write “Hello $firstname $lastname” }
hello -firstname Gregor -lastname Samsa
hello -lastname Samsa -firstname Gregor
function helloInColor($firstname, $lastname, [switch]$red = $false, [switch]$green = $false) { $greeting = “Hello, $firstname $lastname” if($red) { Write-Host -ForegroundColor Red $greeting } if($green) { Write-Host -ForegroundColor Green $greeting } }
Lägg till en annan administrator på site collection
Man kan göra det i CA (Application Mgmnt - Change Site Cltn Admins). Det kan man också snabbt göra med powershell:
Set-SPSite http://contoso -SecondaryOwnerAlias contoso\\admin2
defaultvärde på parametern i powershellfunktioner
Läser ett intressant inlägg om deployskript i powershell. Har upptäckt att man kan stoppa in ett defaultvärde i funktionens parameter. Så i stället för
function hello($name) {
Write-Host $name
}
Kan man köra:
function hello($name = "Gregor") {
Write-Host $name
}
```Mycket smidigt.
parametrar i powershell-funktioner
Man kan skapa funktioner med parametrar som påminner mycket om i C#. Så i stället för:
function Just-Test {
Write-Host $args\[0\]
}
```Skriv:
function Just-Test($param) { Write-Host $param }
if($site -ne $null -and $url -ne $null) {“Url OR Site can be given”; return}
powershell_ise
Powershell ISE (Integrated Scripting Environment) är ett bra verktyg för att skriva powershell-skript med färgmarkering och möjligheten att testköra det. Synd bara att det inte är aktiverat ifrån början i Server 2008. För att [aktivera](Import-Module ServerManager 2 Add-Windowsfeature PowerShell-ISE ) kör följande kommandon i powershell:
Import-Module ServerManager
Add-Windowsfeature PowerShell-ISE
För att sedan starta powershell kör:
powershell\_ise
Förenkla skapandet av utvecklingsmiljön till SharePoint 2010
Jag är fortfarande i mitt sökande efter den perfekta (för mig) utvecklingsmiljön för SharePoint 2010. Fram tills nu har jag arbetat med en virtuell (VMware) maskin som kollegor till mig har konfigurerat. Men jag vill ha kunskapen att göra det själv. Än så länge har jag bara stött på procedurer som är relativt långdragna, fram tills idag. Se på videon på sidan jag länkat nedan. Jag ska testa det och sen förhoppningsvis komma med resultat här. Mitt mål är att lätt komma igång med en maskin som körs som VHD eller native dualboot. Men jag börjar med en virtuell VMware maskin. Ett dygn senare: Igår lät jag skriptet köra (utan config ändringar) och efter många timmar är allt installerat och klart. Dock trailversioner. Men gör man det en natt efter 2 veckor eller när trailen är slut, då kan man börja på en ny maskin igen. Jag gillar skarpt detta skript! Ännu bättre blir det nog när man konfigurerar det att fixa en VHD. Kommer mer om det när det är testat! Länksamling Film från Channel 9 Ladda ner Scriptet här Skriptskaparnas bloggar http://blogs.msdn.com/b/cjohnson/archive/2010/10/28/announcing-sharepoint-easy-setup-for-developers.aspx http://blogs.msdn.com/b/pstubbs/archive/2010/10/27/sharepoint-2010-easy-setup-script.aspx
Powershell med tysk precision
Master Powershell ebookDe som har missat Powershell, läser nog andra sorts bloggar än denna. Så rak på sak: det finns en lovande ebook om Powershell, skriven av Tobias Weltner. Ska absolut läsa den. Ni som har läst, vad tycker ni om den? Master-PowerShell | With Dr. Tobias Weltner i html
Sharepoint + OpenSource = Sant
Om man söker på Sharepoint i codeplex.com får man 729 projekt som är alltså öppna. Det är inte illa. Bland dem finns till exempel Sharepoint Log Viewer. Till det kommer 713 öppna projekt som är taggade ASP.NET som kan användas väldigt mycket i Sharepoint-utveckling. Bland ASP.NET-taggade finns smidiga Telerik Extensions. Powershell är också absolut en tag som man ska söka på i codeplex. codeplex.com är Microsofts officiella OpenSource-portal. Det måste finnas andra sidor där öppna projekt inom Sharepoint och ASP.NET samlas. Tipsa gärna i kommentarer.
Radera en sajt ifrån Powershell
Att radera en sajt ifrån Powershell är väldigt enkelt. Skriv bara:
Remove-SPWeb [http://sharepoint/test](http://sharepoint/test)
Aktivera PowerShell för Sharepoint
Som standard så är snap-in i Powershell för Sharepoint inte aktiverat. Gå in på Powershell och aktivera det genom att skriva in: Enable PowerShell Sharepoint:
Add-PSSnapin Microsoft.SharePoint.Powershell
```Se mer på [social.technet.microsoft](http://social.technet.microsoft.com/Forums/en/sharepoint2010setup/thread/81392f4c-549c-4c4b-a158-99ab8ef8e114).
Retrieve information from AD
Here is a a link you can start with. To test AD, install AD. Then we canplay with it. Take a look those examples, too.
PrincipalSearcher vs. DirectorySearcher
What is the difference?
OU
Here are two examples (one for PrincipalSearcher and the other for DirectorySearcher) to retrieve users from an OU:
//PrincipalSearcher
internal static void ListPrincipalsFromOu()
{
using(var ctx = new PrincipalContext(ContextType.Domain, "takana.local", "OU=SOME\_OU ,DC=takana, DC=local"))
{
using (var up = new UserPrincipal(ctx))
{
using (var ps = new PrincipalSearcher(up))
{
using (var res = ps.FindAll())
{
foreach (var p in res)
{
Console.WriteLine(p.SamAccountName);
}
}
}
}
}
}
//DirectorySearcher
internal static void ListAdEntriesFromOu()
{
const string property = "sAMAccountName";
var ldapcon = new DirectoryEntry("takana.local") {
Path = "LDAP://OU=SOME\_OU,DC=takana,DC=local"
};
var search = new DirectorySearcher(ldapcon);
search.PropertiesToLoad.Add(property);
using (var results = search.FindAll())
{
foreach (System.DirectoryServices.SearchResult result in results)
{
using (var entry = result.GetDirectoryEntry())
{
if (entry.Properties\[property\].Count > 0)
{
Console.WriteLine(entry.Properties\[property\]\[0\]);
}
}
}
}
}
PowerShell
PowerShell är ett sätt att manipulera data och struktur i SharePoint-portalen. Samma uppgifter låter göras med konsoll-applikationer. Fördelen med PowerShell är att man kan skapa skript som är flexibla och kan köras med olika parametrar. PowerShell påminner starkt om shell-skript i Linux. För mig som egentligen kommer snarare från bash-världen. Där har Microsoft låtit sig inspireras starkt :). Det finns en bok om PowerShell, skriven av svenskar, som låter intressant. Man behöver inte heller uppfinna hjul på nytt: det finns färdiga skripts som man direkt. Bara man skriver rätt parametrar. Här är ett ställe där man kan hitta skripts. Det finns många sidor som förklarar hur man skriver skript.