Thursday, November 18, 2010

Map of Renewable Water

Here's the map!

Wednesday, March 25, 2009

PowerShell 1.0 / WMI / IIS 6.0

Here are a few simple PowerShell 1.0 scripts for collecting info from IIS (6.0 on Windows Server 2003 in my case). I'm putting here primarily for my own reference, but hopefulle someone else will find them useful.

write-host "### -----"
$t = get-wmiobject IISWebVirtualDir -namespace "root\MicrosoftIISv2"
$t | ft AppPackageID, AppPackageName, AppRoot, Name
# $t | ft AppIsolated, AppPackageID, AppPackageName, AppRoot, Caption, ' Description, InstallDate, Name, Status
renders


$t = get-wmiobject IISWebVirtualDirSetting -namespace "root\MicrosoftIISv2"
$t | ft AppFriendlyName, Name, Path, Realm
# $t | ft AppIsolated, AppPackageID, AppPackageName, AppRoot, Caption, ' Description, InstallDate, Name, Status
renders

Wednesday, May 14, 2008

Windows Update for Home Network

If you have a home network of Windows PCs, wouldn't it be nice to download the monthly updates once (rather than to each PC independently)? Sure, you could manually copy the files to a network share and manually execute them from each PC. But believe me, that gets to be a hassle! You have to take lots of issues into consideration: 32- or 64-bit; WinXP, Vista, Server 2000, 2003, 2008; Office XP, 2003, 2007; etc.


If you're using some version of Windows Server, it's pretty easy to set up your own Windows Server Update Service (WSUS). Visit http://technet.microsoft.com/en-us/wsus/ to download, install and configure WSUS.


Now, in order to have your PCs reference your WSUS rather than Windows Update, you need to change a couple of policy objects. Since I'm using a domain for my home network, I use the Group Policy Object Editor once and all the PCs pick it up. I believe the same changes will work by applying them to a PC's Local Policies.


Open the Policy Object Editor and navigate to Administrative Templates / Windows Components / Windows Update.







The pane to the right will show the applicable settings for Windows Update.


Now you need to open the policy for Specify intranet Microsoft update service location Properties and provide the URL to your WSUS machine. You may have to check in IIS Manager to determine the correct port.




Your domain-connected PCs will pick up the change on their next policy load. You'll know that the client PCs are using your home WSUS when they appear in the Computers list of the WSUS admin application (Administrative Tools / Microsoft Windows Server Update Services 3.0)



























Friday, November 30, 2007

Windows Policies and Settings for Virtual Machines

Here are a few useful configuration settings for Windows when installing as virtual machines (VMWare, Virtual PC, Virtual Server, etc.) Some of these settings are inappropriate for production systems; I'll try to clarify in those cases.

Clear Pagefile on Shutdown


This will help reduce the VM's disk space demands. Although many VM hosts may take of this directly, to make sure it's cleared out set the following Group Policy Object (GPO)



Local Computer Policy\Computer Configuration\Windows Settings\Security
Settings\Local Policies\Security Options\Shutdown: Clear virtual memory
pagefile

Allow Shutdown Prior to Logon (Non-Production)


It's valuable for personnel who can't log on to a VM (no access, forgot password, etc.) to be able to shutdown the OS w/o logging in. Enable the following GPO:


Local Computer Policy\Computer Configuration\Windows Settings\Security
Settings\Local Policies\Security Options\Shutdown: Allow system to be shutdown without having to log on

Allow Power Users to Shutdown the OS (Non-Production)


Add the local Power Users group to the following GPO:


Local Computer Policy\Computer Configuration\Windows Settings\Security
Settings\Local Policies\User Rights Assignment\Shutdown the system

Monday, November 26, 2007

Visual Studio 2008 Unattended Setup Fails on Longhorn

Problem: Visual Studio 2008 unattended setup from DVD fails on Windows Server 2008 (Longhorn) RC0
Root Cause: Unattended setup is not supported from DVD
Work-Around: Run unattended setup from a network share.

We had the bright idea for unattended Visual Studio 2008 setup. The theory was that we would create the unattend file using setup's CreateUnattend switch, copy it to the DVD and update autorun to trigger the unattended installation. All our devs would need to do is load the DVD, go get a cup of coffee and voilà! VS 2008 would be ready for action.

Unfortunately, it didn't work as expected. After several attempts with minor changes (full path, quoted path, etc.), I finally dug into the log files (in \Users\AppData\Local on Longhorn). Setup creates at least 3 log files in this folder - dd_depcheck_VS_PRO_90.txt, dd_error_vs_procore_90.txt and dd_install_vs_procore_90.txt. The error file was sufficiently helpful. The first 2 lines show:


[11/26/07,15:45:23] vs70uimgr: [2] Admin deployment is not allowed from a
CD/DVD.

[11/26/07,15:45:23] setup.exe: [0] InitializeUIManager(), Start
failure

That's pretty clear and straight-forward.

Wednesday, July 26, 2006

Windows Defender Update Error 0x8024402c

I've been using Windows Defender (beta 2) for a while now, and haven't really had any complaints. Just recently, however, I've been getting message balloons from Defender saying that it hasn't been able to update itself for 14 days, etc. When I manually triggered it to check for updates, it would fail with error code 0x8024402c ( WU_E_PT_WINHTTP_NAME_NOT_RESOLVED).
Searching for info on this lead me to instructions on using msiexec to uninstall the existing virus signatures, etc., but none of this worked.

Then I realized that I had recently switched to using my own Windows Update Server (WSUS). WD must have been seeking the updates from my WSUS rather than windowsupdate.com.

Resolution: Use WSUS Admin to turn on "Definition Updates" and set them to install automatically.

Tuesday, July 18, 2006

Using Enterprise Library Logging Securely with ASP.NET Applications

Using the EL Logging Application Block with ASP.NET is a little tricky -- primarily due to the fact that, in a well secured ASPX app, the logging code will fail due to a lack of write permissions.

First, let's consider the security aspects. In order to keep ASPX apps locked down, I don't allow any users to write to the ASPX app's v-root hierarchy (except Admins & VS Devs groups of course). For example, an ASPX app may map to:
c:\inetpub\wwwroot\WebApp1
with directory hierarchy (under WebApp1 dir) containing folders such as:
bin
SubFolder1
SubFolder1
The WebApp1, WebApp1/SubFolder1 and WebApp1/SubFolder2 dirs may all contain .aspx or other script/executable files. I want the absolute minimum number of users to be able to write to this dir. Otherwise, the more people who have access (even via hacking), the more risk exposure to script injections, etc.

I frequently find that a developer's "solution" is to enable Write permissions on the v-root. This is a horrible mistake and practically unsecures the ASPX app. The correct (and secure) approach is to:
  1. Create a separate directory to store the log files
  2. Grant the (IIS 6.0) App Pool's Identity write permission to the new directory
  3. Configure the logging distributor to point to target the new directory
Create a Directory for Log Files
Simply use Windows Explorer, the Command Prompt or the Installer to create a dir for the log files. I typically create this as a sub-dir of the v-root (e.g., c:\inetpub\wwwroot\WebApp1\Logs)

Grant Write Permission
Again, use Windows Explorer, an Installer Custom Action, or other method to grant Write permission to the appropriate identity. I typically grant Write permission to IIS_WPG since all App Pool Identities must belong to this group. However, if you use multiple app pools with differing identities, then you should grant permission to that specific identity -- this will protect against other App Pool Identities from writing to the Log dir. (If your ASPX app uses end-user impersonation, see the Impersonation Issues section below)

Configure the Logging Distributor
Now that you have created the log dir and given the App Pool's Identity permission to Write to the dir, you need to instruct the Logging Application Block to use this dir for the output log files. Where the output file (typically "trace.log") is stored is controlled by fileName attribute of the sink element in the logging distributor configuration file (typically "loggingDistributorConfiguration.config"). Simply change the fileName attribute by prepending the relative path information.
<loggingDistributorConfiguration>
<xmlSerializerSection Â… >
<enterpriseLibrary.loggingDistributorSettings
defaultCategory="General" defaultFormatter="Text Formatter" ... >
<sinks>
<sink xsi:type="FlatFileSinkData" name="Flat File Sink" fileName=".\Logs\trace.log" ... />
</sinks>

...

</enterpriseLibrary.loggingDistributorSettings>
</xmlSerializerSection>
</loggingDistributorConfiguration>


Impersonation Issues
If your ASPX app employs end-user impersonation, then you'll need to make a choice.
  1. Unimpersonate -- more secure, but a little more difficult to get right
  2. Use custom group which holds Write Permission; add end-users to this group
  3. Stop using end-user impersonation (don't impersonate or impersonate specific identity rather than end-user)
I prefer #1 when #3 is not an option. To implement #1, google for info on System.Security.Principal.WindowsIdentity.Impersonate(IntPtr.Zero). This call has the effect of causing the thread to go back to its original identity. Be sure to use catch/finally with Revert in the Finally block. Otherwise, you'll create a large security hole.

Monday, May 15, 2006

SocketException on host over SmartPass VPN

I have ASP.NET code that attempts to access a particular database over a SmartPass VPN connection. After trying several different ways to avoid the "host not found" SocketException, I copied the ASPX page to a server inside the VPN -- the page worked with no problems. Then I copied the same code into a simple exe (console app); again, it worked fine. I'm at a loss of what the problem is. I know that the ASPX code has DnsPermission, etc., but I haven't been able to find any other clues via google, etc. If you have any ideas, please send them my way.

Thursday, February 02, 2006

SQL 2K: User Defined Types are such a pain!

The promise of User Defined Types is huge, but the headaches may not be worth the effort. With one of my clients we need to be able to easily change UDT definitions and get It Just Works (IJW). For example, we create a StringType_50 that can either be varchar(50) or nvarchar(50). Works fine for table definitions and for sproc params. But if you need to create a temp table in a sproc, you can't use the UDTs. Well, you can create the UDT in the tempdb. We have very restrictive production security issues, and I don't know what the issues are re: ability to create types in tempdb. I will probably mess around with that option later. For now, however, IJW just isn't there w/UDTs.

Friday, January 27, 2006

Don't use SQL Server 2000 Table Variables

SQL 2k's table variable is handy in some ways -- less locking required during transactions, fewer sproc recompiles than temp tables. However, I don't recommend using table variables because:
  • Table variables cannot be defined using User Defined Types. We use UDTs frequently to enforce consistency in even the smallest dbs. Table variables force you to break this best practice and reverse its benefits.
  • Unclear that the variable is a table. The # (or ##) prefix of temp tables gives immediate indication that it is a table. Although good naming conventions could be used to reduce this, naming conventions aren't validated by the compiler.

Friday, January 06, 2006

Power Blogger?

Am I a power blogger or what? It's only been 6 MONTHS since my last entry. Oh yeah -- all over this bloggin' thing.

MS Enterprise Library for GAC

Since I need to use E/L for several apps on a current project, I want to GAC the whole thing. I also want to make it easy for all the devs (of course). Easy solution, right? Just create an installer to gac the E/L assemblies. Well, I had more trouble than one would expect. One of the major hurdles was fairly obscure, so I want to record it here.

Update App Config After GAC'ing Enterprise Library


The biggest gotcha I ran into is that using the E/L config tool for an application sets PublicKeyToken=null in the reference info. This will cause exceptions similar to "Logging.Configuration.ConfigurationException" to occur. To correct this problem, add the PublicKeyToken from the GAC for each E/L assembly to the appropriate location in the app's config files.

Wednesday, June 22, 2005

ASP.NET Apps within SharePoint

While designing a digital asset management system for one of my clients, I considered running the ASP.NET app within SharePoint by simply instructing SharePoint to exclude the path. This is a pretty good idea, if the app can live within the confines SharePoint imposes. Authentication & Session, for example, can't be controlled at the this level.

If your app needs to impersonate, the capabilities are limited. Setting impersonation in the identity element causes the Windows Identity to be IUSR_. Leaving impersonation off causes the Windows Identity to be that of the App Pool (NETWORK SERVICE in my case). In either case, the Page and Thread Principals are empty since the Directory Security setting in IIS allows anonymous. Changing the Dir Sec setting does as you'd expect -- the Page and Thread Principals are set appropriately, impersonation is set, etc. But, now the entire top-level SharePoint site requires authorization (no anonymous access).

ASP.NET Impersonation and Principals

Every now and then I write a simple app to remind myself of what the principals are for the various impersonate config options. Maybe in the future I'll remember to look here.

Assumptions:
  • VRoot requires authentication (anonymous disabled)
  • VRoot's App Pool identity using NETWORK SERVICE
  • "IEUser" is the end user
  • "ImpersonatedUser" is the user config'd in the identity element
















ScenarioPage
User
Thread
CurrentPrincipal
WindowsIdentity
impersonate=falseIEUserIEUserNETWORK SERVICE
impersonate=true;
userName not set
IEUserIEUserIEUser
impersonate=true;
userName set
IEUserIEUserImpersonatedUser

So, the identity of System.Security.Principal.WindowsIdentity is the only one that changes. Page.User should typically be used for IsInRole checks.