Windows 7 Backup encountered a problem

I just recently started to backup my Windows 7 machine using the buildin backup capabilities of Windows 7.

However this doesn’t work as expected. Event though everything seemed to be backed up, I still got an error that a file was skipped during back.

Backup encountered a problem while backing up file C:\Windows\System32\config\systemprofile\Podcasts. Error:(The system cannot find the file specified. (0x80070002))

This is strange. The file does not exists, but why does Windows want to backup that file if it doesn’t exist? There are just some mysteries still to be solved.

However, there seems to be a KB article for this problem. I suppose the problem has something to do with me uninstalling Zune from my system, which most likely created a podcasts folder for me (which I didn’t want in the first place).

So I searched in my profile and found a podcasts folder which I removed.

Batch Parameter

Even though PowerShell is actually becoming the de-facto standard for scripting, there are still a whole lot of batch-scripts which are used for every day tasks and need to be maintained. And event there are always new things to discover.

To pass parameters to a batch-file isn’t really something new. With %1, %2 and so on you can access those parameters within the script. Noteworthy might be the fact, that %1 is the first parameter, while %0 is the name of the script itself.

What I didn’t know so far where some extra variables like %~f0, %~d0, %~p0 … as well as combinations like %~dp0; but then again, I’m not really so much into batch-scripting.

Here is a little overview about what I recently discovered, maybe it helps for someone else:

Description Example
%~f complete path inlc. filename C:\winnt\system32\x.cmd
%~d drive letter C
%~p path \winnt\system32
%~dp complete path C:\winnt\system32
%~sp short path C:\Progra~1\Intern~1 (for C:\Programme\Internet Explorer)
%~x file extension .cmd
%~nx filename incl. extension x.cmd
%~sx short file extension .doc (for .document)
%~a file attributes
%~t date and time of a file
%~z size of a file

First look at Windows 8

At //build Microsoft showed the next version of Windows: Windows 8. Just after the public presentation, a developer preview is actually available for download.

So after downloading 4.8 GB you finally have a ISO image to install. Since I don’t have a spare laptop or desktop around I tried to give Windows 8 a “virutal” spin.

So I fired up my favorite VMWare Workstation, just to discover, that Windows 8 is not (yet) supported on VMWare Workstation (as of this writing I’m running version 7.1.4). As it seems VMWare Workstation 8 is supposed to support Windows 8 (actually the APIC version required by Windows 8). OK, so this doesn’t seem to work out well.

So I though – what the heck, why not give this VirtualBox a turn? A lot of people seem to work with VirtualBox, so it must be worth the effort of taking a closer look. OK, downloaded the bits and installed it on my Windows 7 host.

So let’s see how I can install Windows 8 on VirtualBox. Just create a new virtual machine, specifying it as Windows 7 64-bit and off you go. Just a short while later I’m greeted with the new Windows 8 metro design – this is smooth. Works just like a charm I must say. Should I re-consider my virtual hosting strategy?

Well, anyway. It’s about time to get a first impression of Windows 8 … so some further impressions will follow.

Printer mapping in script

On a side note, a quick way to add printer mappings in a logon script. Even though logon-scripts seem a little out-dated with the power of group policies … non the less.

OK, to map a printer to a local machine you can leverage the rundll32.

rundll32 printui.dll,PrintUIEntry /in /n \\[server]\[printer_share]

Freeing space in Windows

I’ve now been working with my virtual dev-machine for about one year, and it starts to show. I have installed quite a rig of software like SharePoint, Visual Stduio 2008 and 2010, SQL Server 2008, Office 2007 yada-yada-yada.

I just realized that also keeping always up-to-date with all updates and service packs does has some impact on the available disk-space. I know that Windows 2008 itself is not suited for a small drive, but I still wondered how much space the windows-folder could consume.

So I looked into the windows-folder to get a broad overview of what’s actually happening there. And I noticed that the installer-folder is actually eating up quite some space.

Luckily I found a couple of great posts by Heath Steward about the PatchCache folder. To control the size of the PatchCache folder you also might want to take a look at the MaxPatchCacheSize in the windows registry.

For me, that re-gained me about 2.6 GB of disk-space. For a virtual machine running on a laptop this is quite something.

BTW: this is also applicable to other OS, like Windows 7, Vista, XP …

I just hope, that this will not haunt me some time in the future – but then again, it’s just a dev-machine.

Presentation Font Cache is running wild

I just noticed, that my current workstation is actually working. Not that I would not appreciate the effort – but actually this is more than I expected.

So I have a Core2Duo running Windows 7 x64 Ultimate, and usually my CPU should be on an average of 10%. But recently this is up to 50%, one core is always running under full steam.

OK, so taking a look at the process explorer show, that the PresentationFontCache is actually causing all this. But why?

So someone on the MSDN Forums provided some help. First thing I noticed: I can’t stop the service, since it’s currently in startup-mode. And the service is also already set to manually startup.

Because I’m not an admin on my machine, I can’t just go to process-explorer and kill the task. Linux has this neet kill command, which Windows is missing.

OK, so I downloaded PsKill to do the job – but just to figure out, that a new process for the presentation-font-cache is spawning up. Oh-oh!

But I could delete the files, just as the forum-post suggested and this would actually stop the presentation-font-cache from restarting after another round of PsKill.

Showing them all

In Windows Vista as well as in Windows 7 the Control Panel has had a major redesign, compared to Windows XP. All items are now organized into categories, and the actual dialogs might not be accessible right from the control panel.

To overcome this “shortage” you can start-up a new explorer window, and type in the address-bar shell:::{ED7BA470-8E54-465E-825C-99712043E01C}. This will open up a new view, showing about 250 entries for all dialogs within the control panel; happy tuning.

3.300,91

Creating local users – en mass

The traditional way of creating a vast amount of users would include a lot of time as well as patience. Or – maybe just a few lines of (magic) PowerShell code.

So first of all, we have to connect to the local ADSI. This can be done via WinNT://[ComputerName]:

$ComputerName = $env:COMPUTERNAME
$Computer = [adsi]"WinNT://$ComputerName"

This is already the most crucial part. Next we create a new user, set the username, fullname and description and the password.

function Add-User([string]$UserName, [string]$FullName, [string]$Description, [string]$Password)
{
    $User = $Computer.Create("user", $UserName)
    $User.Put("fullName", $FullName)
    $User.Put("description", $Description)
    $User.SetPassword($Password)
    $User.SetInfo()
}

The SetInfo() call ensures, that the data is actually persisted.

Voila, that’s already all you need to get going. Well, in order to create a massive amount of users you will want to create a csv-file of users like:

UserName,FullName,Description,Password
usera,User A,Desc A,passworda
userb,User B,Desc B,passwordb

This can be read with just a single line of code.

function Import-Users([string]$UserFile)
{
    Import-Csv $UserFile | foreach-object { Add-User $_.UserName $_.FullName $_.Description $_.Password }
}

So now all you need is to call Import-Users myNewUsers.csv from the PowerShell command-line and off you go!

Scripting the Active Directory

Background

Well, sometimes the built-in MMC snap-in doesn’t do it all. In this case you need to do more than just add another user. Of course there a bunch of different ways to access your Active Directory. You most certainly can write a nifty c# programm, which could do all kinds of operations. But a lot of times you will end up write some little VBScript, just because it’s so darmn simple.

The Story

For the purpose of illustrating the usage of Active Directory scripting I have a little sample setup. Assume you have a database containing employee data and you want to sync this data with your Active Directory instance. You could further use this data in Active Directory to enable Active Directory aware programs (like SharePoint 🙂 ) to access this data.

The Basics

OK; to get started I will show a little script, which access the Active Directory and does some mass-updating off user-accounts. For example say you want to add employee-numbers to the users accounts.

First of all, you need to connect to the directory. For this you need to know the root path of your Active Directory, or as a convenience you might as well use LDAP://RootDSE instead. OK, let’s get connected to our Active Directory; the code below assumes you have a recordset called rstEmployees which holds our employee data. So we iterate over the recordset:

Sub UpdateActiveDirectoryEntries
        On Error Resume Next
        Dim objRoot, objUser
          Dim intEmployeeCount
        Set objRoot = GetObject(strRootADPath)
        WScript.Echo "Processing records ..."
        rstEmployees.MoveFirst
        While Not rstEmployees.EOF
                WScript.Echo "processing:" & rstEmployees.Fields("EmployeeName") & " (" & rstEmployees.Fields("EmployeeNumber") & ")"
                  Set objUser = GetObject("LDAP://CN=" & rstEmployees.Fields("EmployeeName") & "," & strAllEmployeeADPath)
                  If objUser Is Nothing Then
        WScript.Echo "User '" & rstEmployees.Fields("EmployeeName") & "' could not be found!"
                  Else
                        ShowUser objUser
                          WScript.Echo "Writing ..."
                          objUser.Put "EmployeeID", rstEmployees.Fields("EmployeeNumber").Value
                          objUser.Put "EmployeeNumber", rstEmployees.Fields("EmployeeNumber").Value
                          ' objUser.PutEx ADS_PROPERTY_CLEAR, "EmployeeNumber",  vbNullString
                          objUser.SetInfo
                          ShowUser objUser
                  End If
                  Set objUser = Nothing
                  rstEmployees.MoveNext
          Wend
  End Sub