Blog Index

Tuesday, October 28, 2008

Remote Desktop Cut and Paste does not work

Issue:

When using RDP you may not be able to cut and paste information between your local and remote sessions.

Cause:

The rdpclip.exe processing may not be running on the remote system. Alternatively, the clipboard chain may be incomplete.

Workaround:

Restart the rdpclip.exe process on the remote system.

More Information:
The following article has a good article on Clipboard chaining;

http://blogs.msdn.com/ts/archive/2006/11/16/why-does-my-shared-clipboard-not-work-part-1.aspx

Thursday, October 2, 2008

schtasks /v verbose option may not display expected results

Issue:
When you run "schtasks /query /s [SERVER] /v" on a Windows XP machine, the scheduled tasks utility may not list any tasks.

Symptoms:
The Windows XP schtasks.exe utility (5.1.2600.2180) does not return any output. Task execution does not appear to be impacted by this command line limitation.

Cause:
A scheduled task is configured with a command line exceeding 254 characters.

Executing the command "schtasks /query /s [SERVER]" without the verbose option returns the list of scheduled tasks, however, when the /v option is used to display the extended properties of the task no output is returned.

Workaround:
Use the Windows 2003 version of schtasks.exe (5.2.3790.0) returns task information, although tasks with command lines exceed 254 characters are truncated.

Alternatively, use Windows explorer to view the task information.

Thursday, June 26, 2008

Preventing items from being added to the MFU list

The old addage of "Prevention is better than cure" I have found to be true with relation to removing items from the Most Frequently Used (MFU) start menu list.

The following powershell script prevents the Windows Tour icon and Migration settings wizard from being added to the MFU list. Of course, this could be used to prevent any other number of items from being added to the MFU list.

<<<>>>

$TaskDesc = "Clear MFU List"
$AddRemoveApps_New = ";TourStart.exe;MigWiz.exe"
$AddRemoveApps = Get-ItemProperty HKLM:\Software\Microsoft\Windows\Currentversion\Explorer\FileAssociation
-name AddRemoveApps
Set-ItemProperty HKLM:\Software\Microsoft\Windows\Currentversion\Explorer\FileAssociation
-name AddRemoveApps -value $AddRemoveApps$AddRemoveApps_New


# Test to see if the Registry action succeeded
If ($?) {
Write-Host "Enabled $($TaskDesc)"

} Else {
Write-Host "Error:$($TaskDesc) $($Error[0])"

}

Frequently used programs not automatically added to the Start menu
http://support.microsoft.com/kb/q282066/

Wednesday, June 25, 2008

Preventing users from executing files using Software Restriction Policies

Traditionally I have used NTFS permissions to restrict access for standard user accounts to certain executable files.

Most notably is reg.exe, when providing a managed workstation (SOE) to prevent standard users from accessing the registry. When coupled with Group Policy to restrict access to registry editing tools (regedit) it is effective in preventing access.

One alternative I had overlooked until recently was Software Restriction Policies. These can be applied as per most policies at the local or Group Policy level.

Summary:
A user with full permissions to a directory can be blocked from executing files using the Software Restriction Policies.

Using the "Disallowed" Security level, prevents execution regardless of the NTFS permissions the user holds, using Unrestricted honours the user account NTFS permissions.

Example:
User has Full Control of the folder C:\Test

Create a New Path rule by running GPEdit.msc
Local Security Policy / Software Restriction Policies / Additional Rules (Same location for a GPO)
New Path Rule
Path: C:\Test
Security Level: Disallowed

When the user executes a file from the path, the system prevents execution of the file.

C:\test\notepad.exe
The system cannot execute the specified program.


This could be applied to the SOE reg.exe scenario outlined earlier.

Another use I can see for this is to have a "scripts / tools" directory that the system can execute from Using a local System scheduled task, but those pesky users can't.

The following Microsoft articles list there purported uses of the facility, but this is interesting if nothing else and provides another tool for SOE builds that I hadn't considered using before.


Other rules can be specified to identify software including

Hash. A cryptographic fingerprint of the file
Certificate. A software publisher certificate used to digitally sign a file
Path. The local or universal naming convention (UNC) path of where the file is stored
See also "Registry Paths" as outlined in the reference documents.
Zone. Internet Zone

Using Software Restriction Policies to Protect Against Unauthorized Software

http://technet.microsoft.com/en-us/library/bb457006(TechNet.10).aspx

How Software Restriction Policies Work
http://technet2.microsoft.com/windowsserver/en/library/d24bc8c8-27cc-47ba-9b02-78d9d801e9371033.mspx?mfr=true

Thursday, June 12, 2008

SysPrep may not perform FullUnattend as expected

Issue:

When you supply a SysPrep answer file, SysPrep may not process the answer file as you expect. The Mini-Setup wizard stops processing and requests user input.

Cause:

One cause of this may be the use of comments within the SysPrep file. Sysprep.inf comments are denoted by the semi-colon (;) character. When a comment character is included on a line in the Sysprep.inf file, the complete line is omitted from processing.

Workaround:

Move the comment to a separate line of its own.

Example:

AutoMode=PerSeat ; Licensing Mode usually perseat

change the line as follows;

; Licensing Mode usually perseat
AutoMode=PerSeat

Wednesday, June 4, 2008

GPResult.exe may not complete Group policy report

Issue:
When you run "gpresult.exe /z" on a Windows XP machine, the RSOP may not complete processing.

Symptoms:
The GPResult.exe output is incomplete.

Cause:
A GPO contains the percent ("%") sign character. When the GPResult.exe encounters a % sign in the Group Policy Object, processing is terminated. The version of GPResult.exe with this issue is 5.1.2600.2180.

Typically, the % character may have been used in a Group Policy Computer startup/shutdown script or User Logon/Logoff script, to reference a local environment variable such as %SystemDrive%.

Workaround:
Use the Windows 2003 version of GPResult.exe, this tool is able to parse the % character successfully and completes the RSOP report. Version 5.2.3790.1830 or later of the GPResult.exe tool successfully parses the % character.

Alternatively, the GPMC console is able to generate the RSOP report successfully.

Tuesday, May 27, 2008

Powershell WMI one-liners

The PowerShell WMI capability is quite advanced and provides a vast scope for processing a returned recordset easily and effectively.

Here are just three types of Powershell WMI calls using different namespaces.

Return details about a service
get-wmiobject win32_service -filter "name='alerter'"

Return a users first name from Active Directory
(Get-WmiObject -namespace "root\directory\ldap" -class ds_user -filter "ds_Cn='[UserID]'").DS_givenname

Return details about a specified SMS package
Get-WmiObject -computer [SMSServer] -namespace root\sms\site_[SiteCode] -Query "SELECT * FROM SMS_Package WHERE PackageID='[PackageID]'"

Installing device drivers without the device being present

Having completed a number of SOE unattended installations, I have had reason to be able to install device drivers without the device being present. Attempts to install drivers without the device present using well known driver installation tools such as devcon.exe and dpinst.exe, failed to load the device drivers.

During investigation of the process I reviewed the device installation log file, %SystemRoot%\setupapi.log. In hindsight, the log file is quite aptly named in that functions within the setupapi.dll are called to install devices during windows setup and driver installation programs. This was shown by log entries from the devcon and dpinst programs.

Searches for setupapi.dll eventually showed that the SetupCopyOEMInf function is used to install the devices. Which in turn led to Pyron's SetupCopyOEMInf.exe utility. Whilst the utility is fantastic and performs device installation flawlessly, I was after something that could be manipulated if required.

Enter Powershell!

Utilising managed API calls, I was able to write a powershell script that calls the SetupCopyOEMInf function whilst maintaining the flexibility that scripting offers. Whilst by no means the right solution for everyone, this approach further demonstrates the capabilities of powershell.

In summary, the script installs the device drivers without the device being present.

During a standard user session, the device can be plugged in and the device drivers are loaded without prompting for Administrator credentials.



param(
[string] $DriverDir = $(throw "Please specify a directory of drivers to process")
)

$Scripts = Split-Path $Myinvocation.Mycommand.Path
# Copy a Driver to the OEM path (Install driver without the device being present)
#
#
# References
# http://monadblog.blogspot.com/2005/12/calling-win32-api-functions-through.html
# http://www.pinvoke.net/default.aspx/setupapi.SetupCopyOEMInf
#
# Set Error Handling
$ErrorActionPreference = "SilentlyContinue"
$Me = "SetupCopyOEMInf"
$provider = new-object Microsoft.VisualBasic.VBCodeProvider

$params = new-object System.CodeDom.Compiler.CompilerParameters
$params.GenerateInMemory = $True
$refs = "System.dll","Microsoft.VisualBasic.dll"
$params.ReferencedAssemblies.AddRange($refs)
# Find all the .inf files in the specified directory

$TaskDesc = "Locate INF Files"
$TempDir = Get-ChildItem $DriverDir -filter '*.inf' -recurse
If ($? -eq $False) {
Write-Host "Invalid directory $($DriverDir)"
Exit 1
}

$txtCode = @'
Class CopyOEMInf
Private Declare Function SetupCopyOEMInf Lib "setupapi.dll" Alias "SetupCopyOEMInfA" (ByVal SourceInfFileName As String, ByVal OEMSourceMediaLocation As String, ByVal OEMSourceMediaType As Long, ByVal CopyStyle As Long, ByVal DestinationInfFileName As String, ByVal DestinationInfFileNameSize As Long, ByRef RequiredSize As Long, ByVal DestinationInfFileNameComponent As String) As Long

Public Function Main(ByVal sInf As String, ByVal sDir As String) As Long
Const SP_COPY_NEWER As Integer = &H4
Dim lngResult As Long

Dim ret2 As String
Dim ret3 As String

' Install the driver'
lngResult = SetupCopyOEMInf(sInf, sDir, 1, SP_COPY_NEWER, ret2, 255, 255, ret3)
Return(lngResult)
End Function
end class

'@

$cr = $provider.CompileAssemblyFromSource($params, $txtCode)
if ($cr.Errors.Count) {
$codeLines = $txtCode.Split("`n");

foreach ($ce in $cr.Errors) {
Write-Host "Code compilation error, line $($ce.Line - 1)"
write-host "Error: $($codeLines[$($ce.Line - 1)])"
write-host $ce
}
Throw "INVALID DATA: Errors encountered while compiling code"
}

$mAssembly = $cr.CompiledAssembly

$i = $mAssembly.CreateInstance("CopyOEMInf")
# Process each inf file found


$TempDir foreach {
Write-Host "Installing Driver $($_.Get_FullName().ToString())"

$r = $i.Main($_.Get_FullName().ToString(), $_.Get_Directory().ToString())
}



References
Troubleshooting Device Installation with the SetupAPI Log File
http://www.microsoft.com/whdc/driver/install/setupapilog.mspx
Pyron setupcopyoeminf
http://www.msfn.org/board/Unlimited-number-of-drivers-keeping-th-t43795.html&p=303959#entry303959

http://waynes-world-it.blogspot.com/
Thanks goes to Wayne for introducing the concept and code snippets for compiling managed code from unmanaged scripts.