Click an Ad

If you find this blog helpful, please support me by clicking an ad!

Friday, February 21, 2014

Where are my users' mapping their My Documents folder?

We don't have folder redirection enabled on my domain. Long-term, we'd like to get this put in place, but at some point in time some users' folder were manually redirected. Maybe.

Furthermore, in my project of eradicating Windows XP from the network I have run across instances where users were saving things to their "My Documents" folder (which isn't redirected) instead of to their mapped personal drive (which is the file server that gets backed up). It's a miracle that people haven't lost more data!

What I've done is created a Powershell login script (my first) that collects some key pieces of information and writes to a file on a wide-open share.

#Purpose: Run via Group Policy and give IT data on who has folder redirection turned on, as well as how much data our users have stored locally in their "My Docs" folder.

#Get Computername
$ComputerName = $env:COMPUTERNAME

#Get "My Documents" folder path
$Path = [environment]::GetFolderPath([environment+SpecialFolder]::MyDocuments) 

#Define marker file, which prevents this script from running for that user if found
$MarkerFile = "$Path\DELETEME.TXT"
$MarkerText = "TEST"

#Destination Folder to accumulate these files
$Destination = "\\NASDevice\OpenShare\FolderRedir\"

#If the Marker file doesn't exist.....
If ((Test-Path $MarkerFile) -eq $False){
#Make a MarkerFile so this won't run again
$MarkerText | out-file $MarkerFile

#Get Size of My Docs folder, and convert output to GB
$TotalSize = Get-ChildItem -path $path -recurse -errorAction "SilentlyContinue" | Measure-Object -property length -sum
$SizeOutput = "{0:n6}" -f ($TotalSize.sum / 1GB) + " GigaBytes"

#Put the data together
$SubjectInit = "$ComputerName - $Path - $SizeOutput"
$SubjectInit = $SubjectInit.replace("\","-").replace(":",".")

        #Create the file with the data, then move the file to the share
New-Item -name $SubjectInit -path $path -itemtype "file"
Move-Item "$path\$SubjectInit" $Destination

} #End If

What this process ultimately does is place a file on an open share that has a filename like this:
COMPUTERNAME - DocFolder - SizeOfFiles

The IF statement at the bottom checks the existence of a marker file. If the file doesn't exist, the process continues and creates the marker file. Otherwise, nothing happens. This is so the login script only creates a file on the open share once per user.

The part that I had to research was how to run a Powershell script on logon. Thankfully, The Scripting Guy had a very helpful post. I even learned about WMI filters along the way!

I'm not going to regurgitate his steps to you. They are clear-cut enough.

Since I'm going to create this marker-file within users' MyDocs folders, when I've collected all the data I need and it's time to unlink this GPO, I'll need to alter the script to delete the marker-file if it exists.

Another tidbit: Powershell logon scripts only run on Windows 7, and not Windows XP logins. I don't know about Vista; we don't run it.

Thursday, February 20, 2014

MS SQL Server Backups - Going from Simple to Full Recovery Model

We used to just back up our databases nightly, but we .... ahem... had an issue... and lost some data, so we decided to start doing transaction log and differential backups on a few key databases.

After we identified which databases that we needed to protect, we worked out the following process on a test SQL server using the almighty AdventureWorks database. Microsoft distributes this fully populated test database for SQL admins and devs to play with.

You can find the option to switch the recovery model by right-clicking on the database, selecting properties, and then choosing options.

Important: when switching between Simple and Full recovery models, you have to perform a full backup before the database will start using the transaction log files. If you don't make this switch prior to setting up the subplans (see below), you will not be able to set up the transaction log backup subplan. Also, after switching to transaction logs, you should have a good process in place to monitor free space wherever your files are stored. But you already have that, right?

The schedule that worked for us:
1. Full Backup nightly at 12am.
2. Differential backup at noon and again at 6pm.
3. Transaction Log Backup every 2 hours, starting at 1AM (so on all odd hours: 1,3,5,7, etc).

In SQL Server Management Studio (SSMS), I created a maintenance plan with four subplans:
Full Backup
Diff at noon
TLog every 2 hours
Diff at EOD

For each subplan, I chose the appropriate backup type (full, diff, tlog) and chose the databases. I selected the radio button to "Create a backup file for every database", and chose the D:\DB_Backups path. I then checked the "Verify backup integrity" option and set the drop-down to "Compress Backup".

Set the schedule as required, of course.

Now, we need to take a little detour to create a SQL Server Agent Job. This job has one step:
C:\Windows\System32\WindowsPowerShell\v1.0\PowerShell.exe -File C:\PS\DB_Backup_DR_Mirror.ps1

OMG A POWERSHELL SCRIPT - WHO WOULD HAVE THOUGHT?

Go back to your maintenance plan, and for each subplan you created, drag an "Execute SQL Server Agent Job Task" from the "Maintenance Plan Tasks" toolbar over into the process flow area. Connect the green arrow from your Backup database task to this box, and then set the box to run the job you created to run the Powershell script.

Now, you may be wondering what this Powershell script does!

Its job is to copy the backup files created off-SAN and off-site. My SQL server lives in a VMware environment on a Dell SAN. If the SAN died, I want access to my backups. If the building got hit by an airplane, I want off-site copies. Typical DR.

Here's the script:


#Initial Variables that you will modify on a per-case basis
$SQLServerName = "SQLSERVER1"
$DBName = "ImportantDatabase"

#Variables need that automatically generate
$LocalBackupPath = "D:\DB_Backups\$DBName\*.*"
$OffSANCopyLocation = "\\OnsiteNAS\SQLBackup\$SQLServerName\$DBName"
$OffSiteCopyLocation = "\\OffsiteNAS\SQLBackup\$SQLServerName\$DBName"

#Copy to Local NAS (Off-SAN)
Copy-Item -Path $LocalBackupPath -Destination $OffSANCopyLocation -Force

#Copy to Remote NAS (Off-Site)
Copy-Item -Path $LocalBackupPath -Destination $OffSiteCopyLocation -Force

#Remove copies on the SQL Server itself
Remove-Item -Path $LocalBackupPath -Force

#For off-site location, get the creationtime and delete anything older than 7 days
$Files = (Get-childitem $OffSiteCopyLocation)
Foreach ($file in $files){
$FileAge = ((get-date) - ($file.creationtime)).totaldays
If ($FileAge -gt 7){
remove-item $File.FullName -Force
} #End If
} #End Foreach

#For off-SAN location, get the creationtime and delete anything older than 7 days
$Files = (Get-childitem $OffSANCopyLocation)
Foreach ($file in $files){
$FileAge = ((get-date) - ($file.creationtime)).totaldays
If ($FileAge -gt 7){
remove-item $File.FullName -Force
} #End If
} #End Foreach



There at the end, I'm deleting copies older than 7 days. Since I'm writing to tape on a weekly basis, if someone needs an old copy of the database it's easy enough to pull.

Wednesday, February 19, 2014

PSA: Windows 2003 End-of-Life

I know everyone is in a furor over the impending Windows XP end-of-life, but I thought it might be beneficial to point out that Windows Server 2003 goes end-of-life next summer, on 7/14/15.

NOW is the time to start planning on getting rid of these servers, as there is quite a bit of coordination and testing that goes into relocating a server application.

Other EOL dates of interest include:
SQL Server 2005 4/12/2016
SQL Server 2008 7/9/2019
SQL Server 2008 R2         7/9/2019
Windows Server 2008         1/14/2020
Windows Server 2008 R2         1/14/2020
Exchange Server 2010         1/14/2020
Windows 7 1/14/2020
Office 2010         10/13/2020

You can check other products at the Microsoft Product Lifecycle Search engine.

Tuesday, February 18, 2014

Editing the "Current User" registry hive from inside of a non-admin account

It came to pass that I needed to edit the HKEY_CURRENT_USER Windows registry hive for a particular user the other day. Because this user was not a member of the local admins group, I could not edit the keys I needed to.

I ended up following this method:

1. As the user, log out
2. Log in with an admin account
3. Open Regedit
4. Click on HKEY_USERS
5. Click the File dropdown menu and select "Load Hive"
6. Navigate to C:\Users\<username> (This was a Windows 7 box)
7. In the file name field, enter ntuser.dat. You will not see this file, but it's there.
8. Click Open
9. Give the key a temporary name, I named mine "Coatl"
10. Drill down into Coatl and change what you need to.
11. IMPORTANT: When you are finished, you need to click on the temporary hive, then use the File menu dropdown to "Unload" the hive. Failure to complete this step will result in the user being logged into the machine with a temporary profile.
12. Log out and then back in as the user.