PowerShell – Keeping data secure – Move all items from a users desktop to their My Documents

In my environment I have a constant battle with employees saving items on their desktops and expecting desktop support to be able to recover items when they are lost due to accidental deletion or hardware failure. Desktop remapping is an option but I like to allow users to store personal items on their machine (well at least its better than storing them on the network), hence the simple script below.

The script works by detecting environment variables for the users My Documents (obviously a remapped network location is recommended) and creating a subfolder within it called “Desktop Items”. It then starts a copy process before removing all items except shortcuts and the Personal folder from the users desktop.

If you want to be courteous to your users I also recommend using a GPO preference item to create a shortcut to their “Desktop Items” on their desktop. How you deploy the script is up to you, personally I use group policy preferences to create a shortcut to the powershell.exe in the users start up folder.

###############################################################################
#                                                                             #
# ****************** CREATED BY MAURICE DALY ON 16/01/2014 ****************** #
#                                                                             #
# Moves items from users desktop to a subfolder of their My Documents         #
#                                                                             #
# Version 1.0                                                                 #
# Version 1.1 Added functionality to copy leftover excluded files to MISC     #
#             Directory                                                       #
#                                                                             #
###############################################################################

$docspath = [environment]::getfolderpath("mydocuments") + "\Desktop Items"
$desktop = [environment]::getfolderpath("desktop")
$exclusions = @("*.iso", "*.lnk", "*.mp*", "*.exe", "*.msu", "*.url", "*.wav")
$mediafiles = @("*.iso", "*.mp*", "*.exe", "*.msu", "*.wav")

if (!(Test-Path $docspath))
{
new-item -Path $docspath -ItemType Directory
}

# List items to be copied / deleted
$filedirlist = Get-ChildItem -Path $desktop -Recurse -Exclude $exclusions | where FullName -NotLike *Personal* | where FullName -NotLike *Misc*

# Copy files and folders
$filedirlist |
Move-Item -Destination {
if ($_.PSIsContainer)
{
Join-Path $docspath $_.Parent.FullName.Substring($desktop.length)
}
else
{
Join-Path $docspath $_.FullName.Substring($desktop.length)
}
} -Force -Exclude $exclusions

# Set Miscellaneous folder location
$miscdocspath = [environment]::getfolderpath("desktop") + "\Misc"

# Collect list of legacy files to be moved
$legacyfilelist = Get-ChildItem -Path $desktop -Recurse -Include $mediafiles | where FullName -NotLike *Personal* | where FullName -NotLike *.lnk | where FullName -NotLike *Misc*

# Conditional statement to create a "Miscellaneous" directory for left over legacy files if they exist
if ($legacyfileslist -eq $null)
{
if (!(Test-Path $miscdocspath))
{
new-item -Path $miscdocspath -ItemType Directory
}
}

$legacyfilelist |
Copy-Item -Destination {
if ($_.PSIsContainer)
{
Join-Path $miscdocspath $_.Parent.FullName.Substring($desktop.length)
}
else
{
Join-Path $miscdocspath $_.FullName.Substring($desktop.length)
}
} -Force -ErrorAction SilentlyContinue

PowerShell – Purge Legacy ActiveSync Devices From Exchange 2010

The below script allows you to purge all legacy (inactive for more than 60 days) Active Sync devices from your Exchnage 2010 environment.

################################################################################
#                                                                             #
# ****************** CREATED BY MAURICE DALY ON 06/01/2014 ****************** #
#                                                                             #
# Purge Legacy ActiveSync Devices                                             #
#                                                                             #
# Version 1.0                                                                 #
#                                                                             #
# THIS SCRIPT IS USED AT YOUR OWN RISK. I ACCEPT NO RESPONSIBILITY FOR ANY    #
# ISSUES ARRISING FROM IT                                                     #
#                                                                             #
# Extracts of this script where obtained from Mike Crowley's post on          #
# http://social.technet.microsoft.com/Forums/exchange/en-US/95ca6537-0c74-4c36-b19b-ec647e733722/remove-staleold-active-sync-devices-from-all-mailboxes?forum=exchange2010 #
#                                                                             #
###############################################################################

$LogLocation = "C:\Removed-ActiveSync-Devices.txt"
$Credential = Get-Credential
$DC = $env:LOGONSERVER.Substring(2)

#Initiate Remote PS Session to local DC
$ADPowerShell = New-PSSession -ComputerName $DC -Authentication Negotiate -Credential $Credential

# Import-Module ActiveDirectory
Invoke-Command -Session $ADPowerShell -scriptblock {import-module ActiveDirectory}
Import-PSSession -Session $ADPowerShell -Module ActiveDirectory -AllowClobber -ErrorAction Stop

# Retrieve AD Details
$ADDetails = Get-ADDomain
$Domain = $ADDetails.DNSRoot

$ExchangeServer = Get-ADObject -Filter "(ServicePrincipalNAme -like 'IMAP*')" -SearchBase (Get-ADDomain).DistinguishedName.tostring()  -Properties ServiceDNSName, ServiceClassName | where name -NotLike *SDK* | ForEach-Object {Write-Output $($_.Name + "." + $Domain)} | Get-Random
$ExchangePowerShell = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://$ExchangeServer/Powershell
Import-PSSession $ExchangePowerShell -AllowClobber
cls
Write-Host "Exchange ActiveSync Legacy Device Purge"
Write-Host ""
Write-Host "This script removes all activesync devices which have not successfully syncronised for over 60 days"
$AppChoice = ""
 while ($AppChoice -notmatch "[1|2|3]"){
     Write-Host ""
     Write-Host -ForegroundColor Yellow "[1] Specify Username" 
     Write-Host -ForegroundColor Yellow "[2] All users (use with caution)"
     Write-Host -ForegroundColor Yellow "[3] Cancel"
     Write-Host ""
     $AppChoice = read-host "Please make your selection"
     }
     if ($AppChoice -eq "1"){
            $ActiveSyncUser = Read-Host "Please enter the identity of the mailbox you wish to connect to"
            cls
            Write-Host "Listing ActiveSync devices with no successful sync for 60+ days for user $ActiveSyncUser"
            Get-ActiveSyncDevice -Mailbox $ActiveSyncUser | Get-ActiveSyncDeviceStatistics | where {$_.LastSuccessSync -le (Get-Date).AddDays("-60")} | ft DeviceUserAgent, DeviceModel, DeviceOS, LastSuccessSync
            sleep 10
            $choice = ""
            while ($choice -notmatch "[y|n]"){
            $choice = read-host "Do you want to continue? (Y/N)"
            }
            if ($choice -eq "y"){
            $DevicesToRemove = Get-ActiveSyncDevice -Mailbox $ActiveSyncUser | Get-ActiveSyncDeviceStatistics | where {$_.LastSuccessSync -le (Get-Date).AddDays("-60")}
            $DevicesToRemove | foreach-object {Remove-ActiveSyncDevice ([string]$_.Guid) -confirm:$false}
            Write-Host ""
            Write-Host "Displaying remaining active devices"
            Get-ActiveSyncDevice -Mailbox $ActiveSyncUser | sort name | Get-ActiveSyncDeviceStatistics | ft DeviceUserAgent, DeviceModel, DeviceOS, LastSuccessSync
            }
            if ($choice -eq "n") {
             write-host ""
             write-host -ForegroundColor Yellow "ActiveSync purge cancelled" }
             }
     
          if ($AppChoice -eq "2"){
            write-host ""
            Write-Host "Listing ActiveSync devices with no successful sync for 60+ days for all users"
            Get-ActiveSyncDevice -ResultSize unlimited | Get-ActiveSyncDeviceStatistics | where {$_.LastSuccessSync -le (Get-Date).AddDays("-60")} | ft DeviceModel, GUID, Identity, LastSuccessSync
            sleep 10
            $choice = ""
            while ($choice -notmatch "[y|n]"){
                $choice = read-host "Do you want to continue? (Y/N)"
             }
            if ($choice -eq "y"){
            Write-Host -ForegroundColor Yellow "Purging Legacy ActiveSync Devices"
            $DevicesToRemove = Get-ActiveSyncDevice -ResultSize unlimited| Get-ActiveSyncDeviceStatistics | where {$_.LastSuccessSync -le (Get-Date).AddDays("-60")}
            $DevicesToRemove | foreach-object {Remove-ActiveSyncDevice ([string]$_.Guid) -confirm:$false}
            $DevicesToRemove | out-file "$LogLocation"
            Write-Host -ForegroundColor Yellow "Log file saved to $LogLocation"
            }
            if ($choice -eq "n")  {
             write-host ""
             write-host -ForegroundColor Yellow "ActiveSync purge cancelled" }
             }
         if ($AppChoice -eq "3"){
         Write-Host -ForegroundColor Yellow "ActiveSync purge cancelled."
     }
     else {Write-Host "Script Completed"}

PowerShell – Move Active Mailboxes (Exchange 2010 DAG)

The below script allows you to migrate all active mailboxes from one mailbox server to another within the same Exchange 2010 DAG.


###############################################################################
#                                                                             #
# ****************** CREATED BY MAURICE DALY ON 06/01/2014 ****************** #
#                                                                             #
# Move Active Mailbox Server                                                  #
#                                                                             #
# Version 1.0                                                                 #
#                                                                             #
# THIS SCRIPT IS USED AT YOUR OWN RISK. I ACCEPT NO RESPONSIBILITY FOR ANY    #
# ISSUES ARRISING FROM IT                                                     #
#                                                                             #
###############################################################################

$Credential = Get-Credential
$DC = $env:LOGONSERVER.Substring(2)

#Initiate Remote PS Session to local DC
$ADPowerShell = New-PSSession -ComputerName $DC -Authentication Negotiate -Credential $Credential

# Import-Module ActiveDirectory
Invoke-Command -Session $ADPowerShell -scriptblock {import-module ActiveDirectory}
Import-PSSession -Session $ADPowerShell -Module ActiveDirectory -AllowClobber -ErrorAction Stop

# Retrieve AD Details
$ADDetails = Get-ADDomain
$Domain = $ADDetails.DNSRoot

write-host "This script automates the movement of mailboxes for maintenance purposes"
Write-Host ""
Write-Host "Connecting to Microsoft Exchange Environment....."
$ExchangeServer = Get-ADObject -Filter "(ServicePrincipalNAme -like 'IMAP*')" -SearchBase (Get-ADDomain).DistinguishedName.tostring()  -Properties ServiceDNSName, ServiceClassName | where name -NotLike *SDK* | ForEach-Object {Write-Output $($_.Name + "." + $Domain)} | Get-Random
$ExchangePowerShell = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://$ExchangeServer/Powershell
Import-PSSession $ExchangePowerShell -AllowClobber
cls
Write-Host -ForegroundColor Yellow "Current mailbox locations:"
Get-MailboxDatabase | ft name, servername
Write-Host "Available mailbox servers:"
Get-MailboxServer | ft name, databaseavailabilitygroup
$MailboxTarget = Read-Host "Please enter the name of the server you wish to move active databases to"
$AppChoice = ""
 while ($AppChoice -notmatch "[Y|N]"){
     Write-Host ""
     Write-Host -ForegroundColor Yellow "[Y] YES" 
     Write-Host -ForegroundColor Yellow "[N] NO"
     Write-Host ""
     $AppChoice = read-host "Are you sure you wish to move all active mailboxes to server $MailboxTarget"
     }
     if ($AppChoice -eq "Y"){
        Get-MailboxDatabase | sort name | ForEach-Object {
        Move-ActiveMailboxDatabase -Identity $_.name -ActivateOnServer $MailboxTarget -MountDialOverride 'None' -Confirm:$False
     }
     }
     if ($AppChoice -eq "N"){
     Write-Host "Mailbox move cancelled."
     }