Archive for the ‘PowerShell’ Category

Restoring OneDrive for Business from a user who has been deleted

28th February, 2017 Leave a comment
OneDrive for Business is based on SharePoint and I have seen it referred to in several different ways:
  • OneDrive for Business
  • A SharePoint personal site
  • A SharePoint “my site”
This means that it can be quite difficult to search for the method of restoring a complete OneDrive For Business, but essentially you have to recover a SharePoint site.
There is a Microsoft Knowledge Base article describing OneDrive for Business retention and deletion (KB3042522). Read this before you proceed any further so you can check if it can be recovered by the GUI interface in Office 365.
If you need to recover the OneDrive site, firstly install the SharePoint Online Management Shell and connect to the admin site (the example uses as the Office 365 tenant):
Connect-SPOService -Url
Then obtain a list of all the OneDrive for Business sites that are in the recycle bin:
Get-SPODeletedSite -IncludePersonalSite -limit ALL
Or the following for a specific user:
Get-SPODeletedSite -IncludePersonalSite -limit ALL | where {$_.url -like "*jsmith*"}
Once we have identified the URL, we can use the following command to restore the site:
Restore-SPODeletedSite -Identity
You may also need to give yourself access to the newly restored site:
Set-SPOUser -Site -LoginName -IsSiteCollectionAdmin $true
You can then navigate to the URL and download the required files. Once complete, you can delete the site by appending “/_layouts/15/deleteweb.aspx” to the URL:
By using a bit of scripting we can automate the process a bit (requires PowerShell 3.0 for the Out-Gridview -passthru command):
$domainPrefix = "contoso"
$adminAccount = ""
$Credentials = Get-Credential -UserName $adminAccount -Message "Enter your password."
Connect-SPOService -Url "https://$" -Credential $Credentials
$site = Get-SPODeletedSite -IncludePersonalSite -limit ALL | Out-Gridview -title "Highlight the site and click OK" -passthru
If ($site) {
Restore-SPODeletedSite -Identity $site.Url
Set-SPOUser -Site $site.Url -LoginName $adminAccount -IsSiteCollectionAdmin $true
Write-host "To delete the account, navigate to:`n$($site.Url)/_layouts/15/deleteweb.aspx"

Exchange – Get all active Out Of Office responses

29th October, 2016 2 comments

Today, I got asked to change an Out Of Office reply for a member of staff who had left the organisation. There wasn’t anything rude in what they had written, it just wasn’t as professional as we would have liked.

As we are currently having a larger than usual turnover of staff, it occurred to me that it would be quite useful to have a list of all the active Out Of Office messages.

The following PowerShell script creates an html with the active Out Of Office messages:

$OutputFile = "C:\Scripts\OutOfOfficeReplies.htm"

$autoReplies = Get-Mailbox -ResultSize Unlimited | Get-MailboxAutoReplyConfiguration | Where-Object { $_.AutoReplyState –eq "scheduled" } | select @{Name="User";Expression={$_.identity.Name}}, ExternalMessage, InternalMessage
"<html><head><title>Auto Replies</title><style>" | Out-File -filepath $OutputFile 
"table { border-collapse: collapse; border: 1px solid black; }" | Out-File -filepath $OutputFile -Append
"td { border: 1px solid black; vertical-align: top; }" | Out-File -filepath $OutputFile -Append
"</style></head><body><table>" | Out-File -filepath $OutputFile -Append
"<tr><th>User</th><th>External Message</th><th>Internal Message</th></tr>" | Out-File -filepath $OutputFile -Append

foreach ($autoReply in $autoReplies) {
    "<tr><td>$($autoReply.User)</td><td>$($autoReply.ExternalMessage)</td><td>$($autoReply.InternalMessage)</td>" | Out-File -filepath $OutputFile -Append

"</table></body></html>" | Out-File -filepath $OutputFile -Append
Categories: PowerShell

PowerShell – Get User Principal Name (One-liner)

2nd October, 2016 Leave a comment

As part of our Windows 10/Office 2016 project, we wanted to get the current user’s User Principal Name (UPN). There are several posts on the web with regards on how to do this, including utilising the ADSystemInfo COM object, or obtaining the current user’s ID and then searching Active Directory, however, neither are a clean PowerShell one-liner!

So, after a bit of research, here it is:


This command gets the current user’s Windows Security Principal’s value (or SID), which we then use to bind to its LDAP object. From this object, we can obtain the User Principal Name (or any other Active Directory value).

For our purpose, we wanted to put this value into a user environment variable. Here’s the script I came up with:

$UserUPN = ([ADSI]"LDAP://<SID=$([System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value)>").UserPrincipalName
If ($UserUPN) { [Environment]::SetEnvironmentVariable("UPN", $UserUPN, "User") }

PowerShell – Quick way to iterate through a list of items

29th September, 2016 Leave a comment

In PowerShell, I sometimes I want to quickly iterate through a list of items that another system has produced. One option would be to export the data to a file and read it in, but sometimes it’s not practical or may be quite complicated to parse the file. As a “quick and dirty” solution, it’s possible to create a string spanning multiple lines. We can then use the split method to iterated through each string.


$data = ('65c43d1cb95b8646a0a8d1342d0e9326

$guids = $data.split("`n")

foreach ($guid in $guids) {
Categories: PowerShell Tags: ,

NDR for disabled Active Directory accounts

10th December, 2012 Leave a comment

When staff leave the organisation, are on long term sick, or take a sabbatical we disable their account in Active Directory. This also used to stop emails being delivered to their mailbox (returning a None Delivery Report [NDR] to the sender), which was very useful to let other staff know they were no longer available and stopped important emails sitting in mailboxes that were no longer checked.

Unfortunately, one of the Service Packs (for Exchange 2003, if I recall correctly) “fixed” this issue. Our workaround was to restrict disabled accounts to only accept emails from themselves. Whilst this can be done via the GUI, a script is a lot quicker.

The PowerShell script below adds restrictions to disabled accounts, the removal is removed on accounts that are re-enabled.

# Constants to modify multi-valued AD attributes.

# LDAP path to start search from
$RootOU = "LDAP://OU=User Accounts,DC=domain,DC=net"

Write-Host "Accounts that are disabled but accepting emails"

$search = New-Object DirectoryServices.DirectorySearcher([ADSI]$RootOU)
$Search.PageSize = 1000
$search.filter = "(&(objectCategory=person)(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=2)(!authOrig=*)(|(homeMDB=*)(msExchHomeServerName=*))(!sAMAccountName=command*))"
$results = $search.FindAll()

foreach($result in $results){
   $User = $result.GetDirectoryEntry()
   $distinguishedName = $User.distinguishedName

Write-Host "Accounts that are enabled but not accepting emails"

$search = New-Object DirectoryServices.DirectorySearcher([ADSI]$RootOU)
$Search.PageSize = 1000
$search.filter = "(&(objectCategory=person)(objectClass=user)(!userAccountControl:1.2.840.113556.1.4.803:=2)(authOrig=*)(|(homeMDB=*)(msExchHomeServerName=*)))"
$results = $search.FindAll()

foreach($result in $results){
   $User = $result.GetDirectoryEntry()
   $distinguishedName = $User.distinguishedName
Categories: Accounts, PowerShell

PowerShell Script to export data from Active Directory

9th December, 2012 Leave a comment

I was asked to assist a vendor who was working with our Unix/Oracle team. He was trying to import data from Active Directory into an Oracle database.


I’m no expert on Oracle, but it appears that the LDAP connector simply returned blobs of data, this then had to be parsed, but there seems to be no order to the data returned. The was before we starting looking at converting the objectGUID or seeing if we’d hit the 1000 record AD limit (which SQL Server suffers from).


I’d recently been on a PowerShell course delivered by Microsoft, so I thought I’d write a quick script to export the data. In this case, we output the result to a CSV file, but it is possible to update the database directly. Anyway, here’s the script we used:


# LDAP path to start search from
$RootOU = "LDAP://OU=Regional Accounts,OU=User Accounts,DC=domain,DC=net"

# CSV path
$CSVpath = "C:\TEMP\ADusers.csv"

$search = New-Object DirectoryServices.DirectorySearcher([ADSI]$RootOU)
$Search.PageSize = 1000
$search.filter = “(&(objectCategory=person)(objectClass=user))"
$results = $search.FindAll()

$myData = @()
foreach($result in $results){
   $User = $result.GetDirectoryEntry()
   $myData += ( $User | Select-Object -Property @{Name="objectGUID";Expression={($_.objectGUID | foreach { $ofs="" } { "{0:X2}" -f $_})}},
$myData | Export-csv -path $CSVpath -notype

# Or, you can output to a grid
#$myData | Out-GridView
Categories: Accounts, PowerShell