Tag Archives: PowerShell

Get/Set Active Directory Photos by using PowerShell

Hello everyone. Today a colleague asked me if I know of a simple way to get user pictures from Active Directory. Of course I do and I will show you how you can get and set pictures in Active Directory by using PowerShell.

Important: The following scripts require Remote Server Administration Tools to be installed on your computer if you do not run them on a Domain Controller.

To get pictures from a user in Active Directory simply run the script below and provide a UserName and a Path (For example: C:\example.jpg) where the picture should be stored:

Param([parameter(Mandatory=$true)][alias("User")]$UserName, [parameter(Mandatory=$true)][alias("Picture")]$PicturePath)

Import-Module ActiveDirectory

$user = Get-ADUser $UserName -Properties thumbnailPhoto
$user.thumbnailPhoto | Set-Content $PicturePath -Encoding byte

To update a users photo simply run the script below and provide a UserName and Path of the new picture:

Param([parameter(Mandatory=$true)][alias("User")]$UserName, [parameter(Mandatory=$true)][alias("Picture")]$PicturePath)

Import-Module ActiveDirectory

$photo = [byte[]](Get-Content $PicturePath -Encoding byte)
Set-ADUser $UserName -Replace @{thumbnailPhoto=$photo}

That´s it. You can get/set pictures in Active Directory as simple as this.

As always you can download my scripts from here.




Tagged ,

SharePoint – Configure 24 hour format on all sites

Hello everyone. Today I got the request to change the default time format used on all SharePoint sites to the 24 hour format and I thought I should share how to do this.

Here is the script:

#Add SharePoint PowerShell SnapIn if not already added

if((Get-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue) -eq $null)
Add-PSSnapin Microsoft.SharePoint.PowerShell

$AllSPSites = Get-SPSite -Limit All

foreach($SPSite in $AllSPSites)
foreach($SPWeb in $SPSite.AllWebs)

All you have to do is to run this script on one of your SharePoint Farm servers as SharePoint Administrator and your work is done. That´s it.

As always you can download my script from here.





Tagged ,

SharePoint – Replace Link on Wiki Page

Hello everyone. A while ago I was asked by a colleague if there is a way to replace an old link with a new one in many Wiki pages. He asked me because he needed to replace an old link in a library with hundreds of pages. Pretty hard work if you need to do this manually but fortunately there is a way to do this automatically by using PowerShell.

In the below screenshot you can see one of the example pages which are created when you create a new Wiki Library. And we will try to replace the link I marked with a new one.


To do so we run PowerShell as Administrator (on one of your SharePoint servers) and run my script WikiPageReplaceString.ps1.


As you can see the script successfully replaced the link with the new value.


And here is the script code:

Param([parameter(Mandatory=$true)][alias("Url")]$SPWebUrl, [parameter(Mandatory=$true)][alias("ListName")]$SPListName, [parameter(Mandatory=$true)][alias("Search")]$SearchString, [parameter(Mandatory=$true)][alias("Replace")]$ReplaceString)

#Add SharePoint PowerShell SnapIn if not already added
if((Get-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue) -eq $null)
Add-PSSnapin Microsoft.SharePoint.PowerShell

#Get SharePoint website object
$SPWeb = Get-SPWeb $SPWebUrl
#Get SharePoint list object
$SPList = $SPWeb.Lists[$SPListName]

#Iterate through each item in the Wiki Library
foreach($SPListItem in $SPList.Items)
#Check if $SPListItem contains $SearchString
if($SPListItem["ows_WikiField"] -and $SPListItem["ows_WikiField"].contains($SearchString))
#Check out page

#Replace $Search_String with $Replace_String and update item
$SPListItem["ows_WikiField"] = $SPListItem["ows_WikiField"].replace($SearchString, $ReplaceString);

#Check in page
$SPListItem.File.CheckIn("Checked in by System.");

The script basically does the following:

It will iterate through each item in your Wiki library and check if the string you are searching for exists in the content. If the string is present it will check out the item and replace the string with the new value you entered. After it successfully replaced the string the script will check in your item again and repeat theses steps for the next item until all items have been checked.

Pretty simple, right? So next time you need to update your Wiki libraries you will have this script to do the work for you. I hope you liked my post and as always you can download my script from here.




Tagged ,

BranchCache – Hosted Cache Mode File Server Tutorial

Hi everyone. Today I will show you how you can use BranchCache in Hosted Cache Mode to reduce your WAN traffic and to improve your users experience.

You need the following things:

  • Hosted Cache Server: Windows Server 2012 Standard (Windows Server 2008R2 Enterprise will work too but an Enterprise license is much more expensive)
  • Content Server: Windows Server 2008R2 Standard
  • Clients: Windows 7 Enterprise or higher or Windows 8 Enterprise or higher
  • WAN Emulator: WANem (more information about WANem here)

Test Setup

The below picture shows how I set up my test machines:


Additionally I configured Static Routes for my FileServer and my Client machines. The Static Route of the FileServer forces it to send traffic always over the WANEM machine to the Client machines. The Static Route for the Client machines forces them to send traffic always over the WANEM machine to the FileServer.

This way you can emulate how file downloads will behave over WAN links.


This is what you need to do to make it work:

On the FileServer:

  • Run cmd as Administrator and run the following command:
route –p add <Client Machine IP> mask <WANEM IP>

Important: You need to add a Static Route for every Client machine.

On the Client Machines (on all clients):

  • Run cmd as Administrator and run the following command:
route –p add <FileServer IP> mask <WANEM IP>

On the WANEM machine:

  • All you need to do here is to make sure that packets will be forwarded.

Hosted Cache Server Setup

To setup your Hosted Cache Server you need to do the following:

Run PowerShell as Administrator and enter the following commands:

Install-WindowsFeature BranchCache -IncludeManagementTools
Enable-BCHostedServer -RegisterSCP

That´s all you need to do to make BranchCache work for your Windows 8 Clients.

For Windows 7 Clients there are some additional steps:

If you run cmd as Administrator and run the following command:

netsh branchcache show status all


You will receive a warning that you need a certificate to make BranchCache work for Windows 7 Clients. You can create a certificate for your Hosted Cache Server by following this instructions:

The first step is to install IIS on your Hosted Cache Server and click on Server Certificates.


Now click on Create Self-Signed Certificate…


Choose a friendly name like “BranchCache” and click on OK.


Run mmc as Administrator and add the Snapin Certificates. Choose Computer account and click Next.


Now choose Local computer and click on Finish.


Now open the Export Wizard.


Choose No, do not export the private key.


Next choose DER encoded binary X.509 (.CER).


Now double click your certificate and go to Details. Copy the Thumbprint value and remove all whitespaces.


Now run cmd as Administrator and run the following command:

netsh http add sslcert ipport= certhash=<Thumbprint value> APPID={d673f5ee-a714-454d-8de2-492e4c1bd8f8}


If your run cmd as Administrator again and run the following command again, you will no longer receive the warning mentioned above:

netsh branchcache show status all

That´s it. You have successfully configured your Hosted Cache Server for Windows 7 and Windows 8 Clients.

Content Server Setup

The first thing you need to do is to install the feature BranchCache for network files on your FileServer.


The next step is to create a GPO for your FileServer:


All you need to do is choose Allow hash publication for all shared folder.


The last step is to enable BranchCache on your Share:

Access your Shares Properties and go to Advanced. Now check Enable BranchCache and click on OK. Done.


That´s all you need to do to enable BranchCache on your FileServer.

Windows 8 Client Setup

To setup your Windows 8 Clients to use BranchCache you need to do the following:

Run PowerShell as Administrator and enter the following command:

Enable-BCHostedClient -ServerNames <Hosted Cache Server Name>

That´s it. Your Client is now ready.

Windows 7 Client Setup

To configure your Windows 7 Clients create a new GPO and enable the following BranchCache settings:

  • Turn on BranchCache
  • Set BranchCache Hosted Cache mode


Now enter the FQDN of your Hosted Cache Server.


The next step is to configure your Clients Windows Firewall. Enable the following Inbound Rules:

  • BranchCache Content Retrieval (HTTP-In)
  • BranchCache Peer Discovery (WSD-In)


Now import the Hosted Cache Servers certificate which you exported earlier.



Import your certificate to Trusted Root Certification Authorities.


Additional step:

You can set a network latency value. If your network latency exceeds this value your client will get the data from your Hosted Cache Server instead of the Content Server. If you set a value of 0ms your Hosted Cache Server will be contacted always. (The default network latency value is 80ms).

Important: Please keep in mind that your clients will also get their data directly from your Content Servers if your files are smaller than 64KB.


That´s it your client is now ready.


Access your WANEM machine via http://<WANEM IP>/WANem and setup a bandwidth limit and delay for your test.


Well, that´s it. You successfully configured BranchCache in Hosted Cache mode. Pretty simple, isn´t it?

I hope my post was interesting and useful for you.

You can read more about BranchCache in this document you can get from here.









Tagged , ,

SharePoint – Use PowerShell to copy Library items and column data to another Library

Hello everyone. A few days ago a colleague asked me if there is a quick way to copy Library items and column data to another Library. The reason he asked was because he wanted to create a new website to replace his old one which would satisfy the needs of his users better and he needed all the data stored in that Document Library. This Library contained about 2000 items so he asked me for help since moving them manually would be a real pain. I found some great posts online and came up with a PowerShell script as solution for his problem.

Here is my script:

Param([parameter(Mandatory=$true)][alias("SourceWebUrl")]$SPSourceWebUrl, [parameter(Mandatory=$true)][alias("SourceListName")]$SPSourceListName, [parameter(Mandatory=$true)][alias("DestinationWebUrl")]$SPDestinationWebUrl, [parameter(Mandatory=$true)][alias("DestinationListName")]$SPDestinationListName)

#Add SharePoint PowerShell SnapIn if not already added
if((Get-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue) -eq $null)
Add-PSSnapin Microsoft.SharePoint.PowerShell

#Get data of SharePoint Source List
$SPSourceWeb = Get-SPWeb $SPSourceWebUrl
$SPSourceList = $SPSourceWeb.Lists["$SPSourceListName"]
$SPSourceListColumns = $SPSourceList.Fields
$SPSourceListItems = $SPSourceList.Items

#Get data of SharePoint Destination List
$SPDestinationWeb = Get-SPWeb $SPDestinationWebUrl
$SPDestinationList = $SPDestinationWeb.Lists["$SPDestinationListName"]

#Iterate through all SharePoint List items of Source
foreach($SPSourceListItem in $SPSourceListItems)
#Copy data from Source and create a new item in Destination
$SPNewListItem = $SPDestinationList.RootFolder.Files.Add($SPSourceListItem.Name, $SPSourceListItem.File.OpenBinary()).Item;;

#Iterate through each column in Source
foreach($SPSourceListColumn in $SPSourceListColumns)
#Ignore Read only fields like Created, Modified, etc.
if($SPSourceListColumn.ReadOnlyField -ne $True)
#Copy column data from Source to Destination
$SPNewListItem[$($SPSourceListColumn.InternalName)] = $SPSourceListItem[$($SPSourceListColumn.InternalName)];
#Update current item

The script will do the following:

It will gather all data from the Source Library and create new items in the Destination List. After that the script will update the new items with the column data from the Source Library. The script will ignore Read only fields like Created, Modified, etc.


Please keep the following things in mind when you run this script:

  • The script will only copy the latest version of the items. For example: Only the latest Draft or Published Version. All previous versions will not be copied to the Destination Library. (This wasn´t a problem for me since my colleague did not need the old versions.)
  • If some columns do not exist at the Destination they will simply be ignored. You will not receive errors or notifications.
  • You need to run this script on a server of your SharePoint Farm and need to use an account with appropriate permissions. Otherwise you will not be able to run it. It is also important to know that the column values for the fields Created by and Modified by will be set to this account. This means you will lose the information who created or modified items when you copy them using this script.

As always you can get my script from here.

That´s it. I hope my post was useful for you.





Tagged ,

SharePoint – Send Files as Attachment

Hello everyone. Some days ago a colleague of mine asked me if it is possible to send files from SharePoint as an Attachment via mail. I told him it is possible and I want to show you how you can do this.

It is pretty simple to achieve this. All you need to do is the following:

  • Download the file from SharePoint and store it locally
  • Attach the file to your mail and send it
  • Delete the file

That´s all you need to do. But since we do not want to do it manually every time I created a short PowerShell Script which will do the work for me. (Of course you can do this in C# as well, but PowerShell seemed to be the quickest way to achieve this for me.)

Here is my Script:

#Get File from Webserver
function Get-FileFromWebServer
Param([parameter(Mandatory=$true)][alias("From")]$FromPath, [parameter(Mandatory=$true)][alias("To")]$ToPath)

#Split Path by "/" and store it in $Array
$Array = $FromPath.Split("/")

#Get filename from $Array
$FileName = $Array[($Array.Length-1)]

#Add filename to $ToPath
$ToPath = $ToPath + "\\" + $FileName

#Create new Instance of WebClient
$WebClient = New-Object System.Net.WebClient

#Use default credentials of the user account currently logged in
$WebClient.UseDefaultCredentials = $True
#Download the file from $FromPath and store it in $ToPath
$WebClient.DownloadFile($FromPath, $ToPath)

#Return $ToPath for later use
return $ToPath

#Send mail with Attachment
function Send-Mail
Param([parameter(Mandatory=$true)][alias("SMTP")]$SMTPServer, [parameter(Mandatory=$true)][alias("From")]$Sender, [parameter(Mandatory=$true)][alias("To")]$Receiver, [parameter(Mandatory=$true)][alias("Subject")]$SubjectString, [parameter(Mandatory=$true)][alias("Body")]$BodyMessage, [parameter(Mandatory=$true)][alias("Attachment")]$AttachmentFile)

#Create new SMTPClient Instance
$SMTPClient = New-Object Net.Mail.SMTPclient($SMTPServer)
#Create mail message object
$Message = New-Object Net.Mail.MailMessage($Sender, $Receiver, $SubjectString, $BodyMessage)
#Create Attachment and attach it to the mail message object
$Attachment = New-Object Net.Mail.Attachment($AttachmentFile)
#Send mail

#Dispose $Attachment and $Message

#Download file from SharePoint and send it via mail as Attachment
function Send-FileFromSharePointAsAttachment
Param([parameter(Mandatory=$true)][alias("FromPath")]$FromPathString, [parameter(Mandatory=$true)][alias("ToPath")]$ToPathString, [parameter(Mandatory=$true)][alias("SMTP")]$SMTPServer, [parameter(Mandatory=$true)][alias("From")]$Sender, [parameter(Mandatory=$true)][alias("To")]$Receiver, [parameter(Mandatory=$true)][alias("Subject")]$SubjectString, [parameter(Mandatory=$true)][alias("Body")]$BodyMessage)

#Download file from Webserver and store Download Path
$ToPathString = Get-FileFromWebServer -FromPath $FromPathString -ToPath $ToPathString
#Send the file as Attachment
Send-Mail -SMTP $SMTPServer -From $Sender -To $Receiver -Subject $SubjectString -Body $BodyMessage -Attachment $ToPathString
#Delete the file from Download Path
Remove-Item $ToPathString

#Set variables
$FromPath = "http://sharepoint-portal.com/sites/TeamSite/Documents/ExampleDocument.docx"
$ToPath = "%userprofile%\AppData\Local\Temp"
$SMTPServer = "your-smtp-server.com"
$Sender = "firstname.lastname@company.com"
$Receiver = "firstname.lastname@company.com"
$Subject = "Attachment Test"
$Body = "This mail is a test."

#Execute Send-FileFromSharePointAsAttachment function
Send-FileFromSharePointAsAttachment -FromPath $FromPath -ToPath $ToPath -SMTP $SMTPServer -From $Sender -To $Receiver -Subject $Subject -Body $Body

That´s it. Now you know how you can send files from SharePoint as Attachment via mail. As always you can download my Script from here.




Tagged ,

PowerShell – WellKnownSIDTypes

Today I learned about WellKnownSIDTypes. These WellKnownSIDTypes are useful if the company you are working for uses Microsoft Windows in different languages. For example: If you want to get the members of the Local Administrators group you cannot simply use “Administrators” because the name of the group will be different in each language. So how can you solve this issue? By using WellKnownSIDTypes of course.

Here is an example script that will retrieve the SID of the “Administrators” group for you:

#Get the SID of the Local Group "BUILTIN\Administrators"
function Get-BuiltinAdministratorsSID
$ID = [System.Security.Principal.WellKnownSidType]::BuiltinAdministratorsSid
$SID = New-Object System.Security.Principal.SecurityIdentifier($ID, $Null)

return $SID.Value

As always you can download the example script from here. If you want to know more about WellKnownSIDTypes please have a look at my sources.




PowerShell – Get Current User of Remote PC

Did you ever need to know who is currently logged on on a Remote PC? Today I wrote a little Script which can answer this question.

function Get-CurrentLoggedOnUser

#Get Computer Information from specified Computer
$ComputerInfo = Get-WmiObject Win32_ComputerSystem -Computer $ComputerName

When you run this function it will return a result like this:


Now you know who is logged on on a Remote PC. Simple and easy. As always you can download my Script from here.




PowerShell – Get Default Browser from Remote PC

Did you ever need to know what the Default Browser of a remote computer was? I did. Today I´m going to show you how you can do this using PowerShell and the Microsoft Windows Registry. Here is the Script:


$Registry = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $ComputerName)
$RegistryKey = $Registry.OpenSubKey("SOFTWARE\\Classes\\http\\shell\\open\\command")
#Get (Default) Value
$Value = $RegistryKey.GetValue("")


The above Script will return a String like:

C:\Program Files\Internet Explorer\iexplore.exe" %1

As you can see the Default Browser of my computer is Internet Explorer.

Here the above Script packaged as a function ready to use:

function Get-DefaultBrowser

$Registry = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $ComputerName)
$RegistryKey = $Registry.OpenSubKey("SOFTWARE\\Classes\\http\\shell\\open\\command")
#Get (Default) Value
$Value = $RegistryKey.GetValue("")

return $Value

As always you can download my Script here.







PowerShell – Get Internet Explorer Version from Remote PC

Today a colleague asked me if there is a way to get the current Internet Explorer Version of multiple Remote PC´s (He needed to make sure that all these PC´s had at least Internet Explorer 9 so that his applications would run correctly.). Of course there is a way. I used PowerShell to solve this problem. I wrote a simple PowerShell Script which gets the Internet Explorer Version from the Remote PC´s Registry. Here it is:


$Registry = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $ComputerName)
$RegistryKey= $Registry.OpenSubKey("SOFTWARE\\Microsoft\\Internet Explorer")
$Value = $RegistryKey.GetValue("Version")


The Script above will return the Version Number of the Remote PC´s Internet Explorer when you have the appropriate permissions.

Since I wanted to make my Script a bit more useful I created a function.

function Get-IEVersion

$Registry = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $ComputerName)
$RegistryKey= $Registry.OpenSubKey("SOFTWARE\\Microsoft\\Internet Explorer")
$Value = $RegistryKey.GetValue("Version")

return $Value

And used my new function in another Script.


Import-Module .\Get-InternetExplorerFunctions.ps1

Get-IEVersion $ComputerName

I gave my function to my colleague and he was happy that his problem was solved.

You can download the Scripts above from here.