The circumstance of the nested application data folder

So in my inbox I find a report of an issue where the backup is failing on one of our servers.

The lack of detail error message from the backup software was simply:

[Critical] From: Agent@<ServerName " [/C]"  Time: 10/16/12 20:31:16
	Cannot back up files with a pathname longer than 1024 characters!

No additional info.

This made me scratch my head, as the file system on the server is NTFS, so someone saving a file to a path longer than 260 including the filename would be unlikely. However I have previously seen backup software create this scenario, when backing up MacBooks to a Windows file server.

So first order of business, find the path with the problem.

Using psexec to run powershell as NT AUTHORITY\SYSTEM (to avoid access denied errors):

c:\>psexec -is powershell

and then running the following powershell command:

PS C:\> get-childitem -Recurse -ErrorAction STOP

it would only be a short time before the path was found.

But no joy. The command finished without errors.

So some more head scratching…

Using the backup application, I eventually found that the problem was in a users profile folder, more specifically once the backup application hit the “c:\users\theuser\AppData\Local\Application Data” folder it found another “Application Data” folder and then another underneath and another and another … until it hit the 1024 maximum and threw the error seen above

First the basics, from NT 6.0 (Vista and newer) this Application Data folder is actually a junction pointing to “c:\Users\theuser\AppData\Local”

C:\Users\theuser\AppData\Local>dir /ah
 Volume in drive C has no label.
 Volume Serial Number is F46B-1743

 Directory of C:\Users\theUser\AppData\Local

02/20/2012  02:16 PM         Application Data [C:\Users\theUser\AppData\Local]
02/20/2012  02:16 PM         History [C:\Users\theUser\AppData\Local\Microsoft\Windows\History]
02/20/2012  07:23 PM           775,794 IconCache.db
02/20/2012  02:16 PM         Temporary Internet Files [C:\Users\theUser\AppData\Local\Microsoft\Windows\Temporary Internet Files]
               1 File(s)        775,794 bytes
               3 Dir(s)  12,979,027,968 bytes free


This has been put in place for legacy application support.

Under normal circumstances, this folder cannot be opened in Windows Explorer.

You can access the folder from an elevated command prompt, but that will just land you back in the “c:\Users\theuser\AppData\Local” folder

So why did the backup application decide that there was a newer ending nested group of “Application Data" folders?

Well the nested folders where actually there. But why…

The default permissions for the “Application Data” junction:

C:\Users\theUser\AppData\Local>icacls "Application Data"
Application Data Everyone:(DENY)(S,RD)
                 NT AUTHORITY\SYSTEM:(I)(OI)(CI)(F)

Notice the explicit DENY set for Everyone.

If this permission is removed, for instance by an admin who does not know that it is supposed to be there, then a browse into the folder with Windows Explorer will actually create a new folder, so that we now have “c:\Users\theUser\Appdata\local\Application Data\Application Data”

Do this enough times and we hit the error with the backup application. The above nested folder creation can also happen when using Robocopy

But why did the simple powershell test not catch this. Well, that is because I am a dork, and forgot about the fact of hidden folders… the command should have been:

PS C:\> get-childitem -Recurse -Force -ErrorAction STOP

Well now that this is cleared up, a cleanup task is required to remove the broken application data folder, but how to do that. Using Windows explorer – error. Appears that the mischievous admin broke some more permissions. That is easy to fix. First take ownership:

C:\Users\theUser\AppData\Local> takeown /F * /A /R /D Y

then, reset permissions:

C:\Users\theUser\AppData\Local> icacls * /reset /T /Q

But that errors out as well.

So I need a program that ignores permissions and can delete these long paths, and any file which may reside in the folders. Robocopy can do that:

Create a empty folder, say c:\dummy, then:

C:\Users\theUser\AppData\Local> Robocopy c:\dummy "C:\Users\theUser\AppData\Local\Application Data" /B /Purge

The /B instructs Robocopy to run in backup mode, which disregards file permissions. /Purge removes anything in the destination which is not in the source.

Final step is to fix the permissions on the Application data folder.

Note of course that the above does not consider the impact on the users profile, so use at own risk.


Categories: Windows Server

Export DHCP leases to HTML– version 2

An updated version of the previous script, now with the ability to export the MAC to the HTML as well as dumping all scopes to individual HTML and .csv files


$sort = "DNS" #output file sorting, can also be "DNS" or "MAC" (MAC only if includeMAC switch selected

Function DumpDHCPScope (){

$scopedump = (netsh dhcp server $DHCPServer scope $subScope show clients 1)
$lines = @()
foreach ($i in $scopedump){
	if ($i -match "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"){
		If ($i -match "[0-9a-f]{2}[:-][0-9a-f]{2}[:-][0-9a-f]{2}[:-][0-9a-f]{2}[:-][0-9a-f]{2}[:-][0-9a-f]{2}"){	
			$lines += $i.Trim()
$csvfile = @()
foreach ($l in $lines){
	$Row = "" | select IP, DNS
	If ($IncludeMAC -eq $true){$Row = "" | select IP, DNS, MAC}
	#$l = $l -replace '[0-9a-f]{2}[:-][0-9a-f]{2}[:-][0-9a-f]{2}[:-][0-9a-f]{2}[:-][0-9a-f]{2}[:-][0-9a-f]{2}', '' #removes MAC address
	$l = $l -replace ' - ',','
	$l = $l -replace '\s{4,}',''
	$l = $l -replace '--','-'
	$l = $l -replace '-D-','-'
	$l = $l -replace '[-]{1}\d{1,2}[/-]\d{1,2}[/-]\d{4}',''
	$l = $l -replace '\d{1,2}[:]\d{2}[:]\d{2}',''
	$l = $l -replace 'AM',''
	$l = $l -replace 'PM',''
	$l = $l -replace '[,][-]',''
	$l = $l -replace '\s{1}',','
	$l = $l -replace '[,]{2,4}',','
	$l = $l -replace '[,][-]',''
	#$l = $l + "`n"
	$Row.IP = ($l.Split(","))[0]
	#$Row.SubNetMask = ($l.Split(","))[1]
	if ($IncludeMAC -eq $true){$Row.MAC = ($l.Split(","))[2]}
	$Row.DNS = ($l.Split(","))[3]
	$csvfile += $Row

$csvfile | sort-object $sort | Export-Csv "C:\TMP\ScriptOut\$subScope-DHCPOut-List.csv" -NoTypeInformation

$a = "<style>"
$a = $a + "body {margin: 10px; width: 600px; font-family:arial; font-size: 12px;}"
$a = $a + "TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}"
$a = $a + "TH{border-width: 1px;padding: 2px;border-style: solid;border-color: black;background-color: rgb(179,179,179);align='left';}"
$a = $a + "TD{border-width: 1px;padding: 2px;border-style: solid;border-color: black;background-color: white;}"
$a = $a + "</style>"

"Please contact in case of any questions" | Out-File "C:\TMP\ScriptOut\$subScope-DHCP-List.html"
$csvfile | sort-object $sort | ConvertTo-HTML -head $a | Out-File -Append "C:\TMP\ScriptOut\$subScope-DHCP-List.html"
get-date -Format dd/MM/yyyy@HH:mm:ss  | Out-File -Append "C:\TMP\ScriptOut\$subScope-DHCP-List.html"

}#End Function DumpDHCPScope

#Main Script

if ($Scope -eq "ALL"){
	$scopelist = @()
	$AllScopes = (netsh dhcp server $DHCPserver show scope 1)
	foreach ($i in $AllScopes){
		if ($i -match "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"){
			$scopelist += $i.Trim()
	Foreach ($i in $scopelist){
		$i = $i -replace '\s{2,}',''
		$i = $i -replace '- ',','
		$i = $i -replace '-',','
		DumpDHCPScope $i.Split(",")[0]
Else {
	DumpDHCPScope $scope

Example commandlines:

Export-dhcptohtml.ps1 –dhcpserver –scope –includemac

This will dump the DHCP scope including the MAC to an HTML file as well as a csv file.

Export-dhcptohtml.ps1 –dhcpserver -scope ALL

This will dump all scopes on the dhcp server to individual HTML and .csv files.

Do post a comment, suggestion or request.

[Update 29-05-2012] – Added missing – (dash) in second example


Categories: DHCP, Powershell Scripts

Copy certificates from one server to another

So for some reason, which until now remains a mystery, certificates where missing in the Trusted root certificate authorities certificate store on one of our servers.

Of course one of the missing ones, was the one needed for a main part of the servers purpose, so that had to be fixed.

While the certificates mmc does permit the export on the source server and the import onto the broken one, working in the GUI, is just….

So I cooked up a Powershell script to do the job for me:

Compares a given certificate store between 2 Windows machines. Copies missing to target if specified

The script compares the specified certificate store of the source machine against the target machine. 
If the Write switch is specified, the missing certificates are copied from the source machine to the target machine

.PARAMETER SourceServer
Source Machine name

.PARAMETER TargetServer
Target Machine name

Certificate store to be checked
Possible values of the store: 
My - Personal Store
Root - Trusted root certificate authorities
CertificateAuthority - Intermediate certificate authorities
AuthRoot - Third-party certificate authorities

If specified, certificates missing on the target server will be copied to the target server


Console output

Check-MachineCerts.ps1 -SourceServer "SomeServer" -TargetServer "SomeServer" -certstore "AuthStore"
Outputs the certificates missing in the Third-party certificate authorities store on the target machine as compared to the source machine

Check-MachineCerts.ps1 -SourceServer "SomeServer" -TargetServer "SomeServer" -certstore "My" -write
Outputs the certificates missing in the Personal Store on the target machine as compared to the source machine. 
Copies the missing certificates to the target machine

by theAdminGuy -
#Connect to the source Root store (readonly)
$sourceStore = New-Object System.Security.Cryptography.X509Certificates.X509Store("\\$SourceServer\$CertStore","LocalMachine")
#connect to the target store (readwrite)
$targetStore = New-Object System.Security.Cryptography.X509Certificates.X509Store("\\$TargetServer\$CertStore","LocalMachine")

$sourceCerts = $sourceStore.certificates
$targetCerts = $targetStore.certificates

Function CheckPrecense(){
	[int]$intCertFound = "0"
    $script:rtrCheckPrecense = "CertNotFound"
    ForEach ($targetcert in $targetCerts){     
        $test = $sourcecert.Equals($targetcert)
        if ($test -eq $true){
    If ($intCertFound -ne "0"){
            $script:rtrCheckPrecense = "CertFound"
} #end function 

foreach ($sourcecert in $sourceCerts){
    CheckPrecense $sourcecert
    If ($rtrCheckPrecense -eq "CertNotFound"){
        Write-Host `n`n $sourceCert.Subject " was not found on " $TargetServer
        If ($write -eq $true){
        	Write-Host `n "Copying Certificate from " $SourceServer `n

Don’t judge me by the fact that the .Synopsis part of the script takes up half the lines in the script, but not being a programmer by trade, I am trying to improve on my documentation skills (as well as making myself able to reuse the script once I have forgotten it’s original purpose)

The script can be easily modified to also remove certs from the target, which is not present on the source.

Do let me know all your input, thoughts etc.



Powershell One-Liners – Process Monitor

As a server admin, I often face a situation where I have to perform an action on the server, but some process is running, and I have to wait.

Rather than sitting around checking the server every 5 minutes, I set a Powershell one-liner monitor with notification:

powershell.exe -command "& {if (! (get-process -name TheService -erroraction SilentlyContinue)){Send-MailMessage -SmtpServer 'theSMTPServer.void.null' -from -To 'theadmin@void.null -Subject 'TheService is not running, check theServer'}}"

I simply add the above line same as in the Folder cleaner


Powershell One-liners – Folder cleaning

Some application just log to much, and the log files tend to get huge.

Or maybe you have a situation where you just don’t need the log’s from the last 2 years, but would like to retain a few days back, in case of error:

Windows Scheduled task and Powershell to the rescue


powershell.exe -command "& {get-childitem -Path e:\IIS_Logs -Recurse| %{if ($_.CreationTime -lt ([DateTime]::Now.AddDays(-5))){remove-item $_.FullName}}}"

This will delete files older than 5 days in the targeted folder (IIS_logs) and all subfolders

I have tried to wrap this in a schtasks command, so far been unsuccessful.

In the Windows Server 2008 R2 GUI:

  • Task Scheduler
  • Create a basic task
  • Give it a name and a description
  • Choose the Task trigger and the properties for the selected trigger
  • Choose the action (start a program)
  • Add the path for powershell.exe in the program/script box and everything following to the Add arguments (optional) box
  • image
  • Review and Finish.

Powershell One-liners – IP scanner

So why use powershell? I even heard someone say “this powershell is so over-rated, what does it offer, that cannot be done with cmd.exe and a another tool?”

Well, to me, that is exactly it, what does powershell offer, which cannot be done with cmd.exe?

What if you wanted just to check a defined range of IP’s in you managed subnet, to find which ones have live hosts on them?

[PS]# 1..100 | %{ping -n 1 -w 15 11.2.7.$_ | select-string "reply from"}

Reply from bytes=32 time=5ms TTL=122
Reply from bytes=32 time=7ms TTL=122
Reply from bytes=32 time=6ms TTL=122
Reply from bytes=32 time=6ms TTL=122
Reply from bytes=32 time=6ms TTL=122
Reply from bytes=32 time=6ms TTL=122
Reply from bytes=32 time=6ms TTL=122
Reply from bytes=32 time=6ms TTL=122
Reply from bytes=32 time=6ms TTL=122

This one-liner ping’s the range from 1 to 100 and returns the machines which replied.

The point here is not, that only Powershell can do this on Windows, and I know that ping.exe is not a native powershell cmd-let and what if the host does not respond to ICMP…bla bla.. Smile

But this method is simple, fast and intuitive. No need for starting up a dedicated application, no fiddling with scripts, just get the job done, which in turn leaves more room for other stuff.


Remove privileged folder in Windows 7

Ever found yourself in the situation where you wanted to delete a folder in Windows 7, but you can’t because it has special rights in some way?

An example of such a folder could be the %windir%\winsxs.

In my case I had attached a virtual disk file (.vmdk) from one virtual machine to a new virtual machine.

So I wanted to clean this disk of the unneeded Windows folder, but as this folder as well as most of the subfolders are owned by TrustedInstaller, not by the local Administrators group. For the %windir%\winsxs folder, the administrators group as well as the local system user (NT Authority\System) has only read access to the files.

In order to delete the folder you have to do two things:

  1. Take ownership of the folder and files
  2. Grant the required user at least write access to the folder and files so they can be deleted

The above can be done using the %windir%\system32\takeown.exe and the %windir%\system32\Icacls.exe

If doing this on one machine, then you could just run the respective command lines:

  • takeown.exe /F d:\windows /R /D Y
  • Icacls.exe d:\windows /grant *<UserSID>:(F) /T /C

But if you ever have to repeat it, then it should have been scripted:

#Set-RestrictedFolderRights -folder
if($Folder -eq ""){Write-Host "Please specify folder...";Break}

Function Get-UserSID(){
	$sCurrentUser = [system.environment]::UserName
	$sCurrentUserdomain = [system.environment]::Userdomain
	$objUser = New-Object System.Security.Principal.NTAccount($sCurrentUserdomain, $sCurrentUser)
	$strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier])
}#end function Get-UserSID

#Main Script
$sSysFolder = ([system.environment]::SystemDirectory)
$sArgsA = '/F '+$Folder+' /A /R /D Y'

#grant ownership of the folder and all subfolders to the administrators group..
Start-Process -wait -FilePath "$sSysFolder\takeown.exe" -ArgumentList $sArgsA

#grant the logged on user full control of the folder and it's entire content
$sArgsB = $folder+' /grant *'+(Get-UserSID)+':(F) /T /C'
Start-Process -wait -FilePath "$sSysFolder\icacls.exe" -ArgumentList $sArgsB

The script takes the target folder as a parameter and then sets the rights:

PS > Set-RestrictedFolderRights -folder d:\Windows

After that the folder can be deleted.

A word of caution, there is no error checking in the script, so if you target the %systemroot% (usually c:\windows), the rights will be altered. As the script only adds permissions, the impact is not that huge, if the folder is not deleted after. But the rights are set in this manner for a reason


Categories: Powershell Scripts
%d bloggers like this: