Windows 10 (1607) shows OneDrive in the Explorer navigation pane

Despite setting “Prevent the usage of OneDrive for file storage” under “Computer Configuration/Administrative Templates/Windows Components/OneDrive”, OneDrive is still shown in the File Explorer navigation pane.

It transpires that the OneDrive client included with Windows 10 (1607) does not seem to remove the OneDrive icon from File Explorer. Updating the OneDrive client fixes this issue, unfortunately, this is a per-user upgrade. To update the default client, execute the following:


The OneDrive client will be then be updated to the latest version.


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"

Get User Principal Name – Part II

10th December, 2016 Leave a comment

Whilst I was researching an unrelated issue, I happened upon the following article:

Whilst the user was looking to put the userSharedFolder attribute into an environment variable, the solution allows almost any Active Directory attribute to be access and stored, including the User Principal Name. It uses a feature of Group Policy Preferences that I wasn’t previously aware of.

I prefer this to my previous solution, as it allows for centralised management, whereas, with PowerShell, I have to push the script out to the workstations somehow.

Here are the instructions on creating the Group Policy Preferences Environment Variable:

  1. Create a new GPO (or edit one that has user settings)
  2. Go to User Config -> Preferences -> Windows Settings -> Environment
  3. Create a new Environment variable
  4. Action: Update
    Select: User Variable
    Name: UPN
    Value: %_UPN%
  5. Click the Common tab.
  6. Enter a description: “Create an environment variable called UPN and populate it with the UserPrincipalName attribute for the user, as held in Active Directory.”
  7. Tick “Item-level Targeting” and click “Targeting…”
  8. Select New Item -> LDAP Query
  9. Filter: (&(objectClass=user)(sAMAccountName=%USERNAME%))
    Binding: LDAP:
    Attribute: userPrincipalName
  10. Environment variable name: _UPN
  11. Click OK, OK

You can then reference the environment variable subsequent scripts that run after the GPO has applied.

It may be possible, by using multiple filters, to build a variable from different Active Directory attributes, but I haven’t tried this.

Categories: Active Directory Tags:

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: ,

Batch file to check if user is a member of an Active Directory Group

9th August, 2013 Leave a comment

Due to a limitation of our software deployment software, I was asked if it was possible to copy a file based on an Active Directory group membership. After a bit of research I decided the best course of action was to utilise the DSquery and DSget commands that are part of the Windows 7 operating system.

Let’s examine the core of the script below.

  • Firstly, we specify the distinguishedName of the group that we want to check and put it into a variable – we’ll use this later in our code.
  • We then use “dsquery user -samid %username%” to obtained the distinguishedName of the currently logged in user by using the %username% environment variable, which is the SAMid (sAMAccountName) in Active Directory.
  • We pipe the result into “dsget user -memberof -expand”. This generates a list of distinguishedNames of all the group that the user is a member of. The “-expand” parameter ensures that all nested groups are listed as well.
  • We then pipe the result of this into the FindStr utility and search for the group name the we specified at the start of the process. We perform a case insensitive search and also redirect STDOUT and STDERR to NULL to stop anything being shown on the screen.
  • Finally, we check the %ERRORLEVEL% value to determine if the string has been found or not.

And here’s the script:

set group="CN=Network Team - ICT Services,OU=Test,DC=domain,DC=net"
dsquery user -samid %username% | dsget user -memberof -expand | findstr /i /c:%group% 1>NUL 2>NUL
If %ERRORLEVEL% EQU 1 echo Not found group!!
If %ERRORLEVEL% EQU 0 echo Found group!!