At my current project I am investigating the software used within that organization. As part of this I want a overview of all the URL’s (*.url) and shortcuts (*.lnk) used. I created two PowerShell scripts to scan a server location (eg. the fileshare containing the roaming profiles of the users) and report all the found *.url / *.lnk files and write these to a csv file.

Get_URL.ps1

$strLocation = "Y:\"
$strExtension = "*.url"
$objUrls = @()
$strResultFile = "D:\Work\output\URLs " + [DateTime]::Now.ToString( "yyyy-MM-dd hh-mm-ss" ) + ".csv"
$intCounter = 0

$sh = New-Object -ComObject "WScript.shell"

Write-Host "Start..."

$objFolders = Get-ChildItem $strLocation -Recurse -Filter $strExtension
$intCounterMax = $objFolders.Length

Write-Host "Processing URLs..."

ForEach ($I in $objFolders)
{
	[string]$x = $I.FullName

	if ($x.Contains("["))
	{
		Write-Host "* Skipped"$x" *"
		$objTemp = New-Object PSObject
		$objTemp | Add-Member -membertype Noteproperty -Name Name -Value $I.Name
		$objTemp | Add-Member -membertype Noteproperty -Name Owner -Value "*Skipped*"
   	   	$objURLs += $objTemp
	}
	else
	{

		$strUserId =($x.Split("\"))[1]
		$strOwner = (get-QADUser $strUserId).Name
		if ($strOwner) {} else {$strOwner = "<unkown>"}
		$strName = $I.Name

		$size = Get-ChildItem $x -rec |measure-object -property length -sum

		if ($size.Sum)
		{
			$y = get-content $I.FullName -ErrorAction SilentlyContinue
			if ($y.length)
				{
				if (($y.GetType().name) -eq "object[]")
					{
						$strUrl = ($y[1].Split("="))[1]
					}
				else
					{
						$strOwner = "*Skipped*"
						$strUrl = ""
					}
				}
		}
		else
		{
			$strUrl = "-"
		}

		$objTemp = New-Object PSObject
		$objTemp | Add-Member -membertype Noteproperty -Name Name -Value $strName
		$objTemp | Add-Member -membertype Noteproperty -Name Owner -Value $strOwner
		$objTemp | Add-Member -MemberType Noteproperty -Name Url -Value $strUrl
		$objTemp | Add-Member -membertype Noteproperty -Name FullName -Value $I.FullName
		$objURLs += $objTemp
	}

	$intCounter++

	Write-Host "["$intCounter"/"$intCounterMax]" User: " $StrOwner " " $strName
}

#$objURLs

$objURLs | Export-Csv $strResultFile -noTypeInformation

Write-Host "Done"

Get_LNK.ps1

$strLocation = "y:\"
$strExtension = "*.lnk"
$objShortcuts = @()
$strResultFile = "D:\Work\output\shortcuts " + [DateTime]::Now.ToString( "yyyy-MM-dd hh-mm-ss" ) + ".csv"
$intCounter = 0

Write-Host "Start..."
Write-Host "Getting shortcuts..."

$z = Connect-QADService

$sh = New-Object -ComObject "WScript.shell"
$objFolders = Get-ChildItem $strLocation -Recurse -Filter $strExtension
$intCounterMax = $objFolders.Length

Write-Host "Processing Shortcuts..."

ForEach ($I in $objFolders)
{
	$x = $sh.CreateShortcut($I.fullname) 

	$strUserId = (($x.FullName).Split("\"))[1]
	$strOwner = (get-QADUser $strUserId).Name

	$objTemp = New-Object PSObject
	$objTemp | Add-Member -membertype Noteproperty -Name Owner -Value $strOwner
	$objTemp | Add-Member -membertype Noteproperty -Name Name -Value $strName
	$objTemp | Add-Member -MemberType Noteproperty -Name TargetPath -Value $x.Targetpath
	$objTemp | Add-Member -MemberType Noteproperty -Name Arguments -Value $x.Arguments
	$objTemp | Add-Member -MemberType Noteproperty -Name WorkingDirectory -Value $x.WorkingDirectory
	$objTemp | Add-Member -membertype Noteproperty -Name FullName -Value $x.FullName
	$objShortcuts += $objTemp

	$intCounter++

	Write-Host "["$intCounter"/"$intCounterMax]" User: " $StrOwner " " $StrName
}

$objShortcuts | Export-Csv $strResultFile -noTypeInformation

Write-Host "Done."