Chapter 10. Disks and File Systems

On any given day, an organization can generate a staggering amount of data. Maintaining the physical disks and logical disk drives that contain this data is a critical task. System administrators must ensure the preservation of important data for future use, guarantee that users have access to data, and provide adequate free disk space for users to carry out their daily duties. Scripts can be powerful tools that assist system administrators in managing disks, file systems, and other parts of the storage management infrastructure.

In This Chapter

Disks and File Systems Overview

Not too long ago, the idea of storage management would have been nonsensical to most system administrators. In the early days of the personal computer, very few computers had hard disks and even fewer needed them. Considering that both the operating system and an application could fit on a floppy drive, the primary task in storage management lay in ensuring that there was always a box of floppy disks in the storeroom.

Needless to say, things have changed considerably in the past 15 years or so. Storage management is now one of the more important duties charged to system administrators, administrators who must manage and monitor hundreds, thousands, and maybe even tens of thousands of disk drives, all with different capacities and characteristics. System administrators must deal with multiple file systems; they must ensure that all users have adequate disk space; and they must impose quotas, if necessary, to ensure that users do not exceed their allotted disk space. System administrators must also quickly identify and repair problems with disks or file systems before those problems affect scores of users.

Because storage management is a huge undertaking, Microsoft provides several scripting solutions that make it easier for system administrators to manage disks and file systems throughout an organization. You can use these scripts on computers running Microsoft® Windows® 2000 operating systems.

Managing and Monitoring Disk Drives

Physical hard disk drives are the primary storage medium for information in any computing environment. Although organizations often use devices such as tape drives and compact disc drives for archiving data, these devices are not suited for day-to-day storage of user data. Only physical hard disks offer the speed and ease of use required for storing data and for running applications and the operating system.

To efficiently manage data, it is important to have a detailed inventory of all your physical disks, their capabilities, and their capacities. You can use the Win32_DiskDrive class to derive this type of inventory. As shown in Table 10.1, you can use the Win32_DiskDrive class to enumerate the disk drives installed on a computer and to return data such as the type of interface used by the drive, the drive manufacturer and model number, and the number of tracks, cylinders, sectors, and heads that compose the drive hardware.

Table 10.1. Win32_DiskDrive Properties

Property

Description

BytesPerSector

Number of bytes in each sector for the physical disk drive.

Capabilities

Array of capabilities of the disk drive. Values include:

  • 0— Unknown

  • 1— Other

  • 2— Sequential Access

  • 3— Random Access

  • 4— Supports Writing

  • 5— Encryption

  • 6— Compression

  • 7— Supports Removable Media

  • 8— Manual Cleaning

  • 9— Automatic Cleaning

  • 10— SMART Notification

  • 11— Supports Dual-Sided Media

  • 12— Ejection Prior to Drive Dismount Not Required

CompressionMethod

Algorithm or tool used by the device to support compression.

Description

Description of the disk drive.

DeviceID

Unique identifier of the disk drive with other devices on the system.

Index

Physical drive number of the given drive. A value of 0xFF indicates that the given drive does not map to a physical drive.

InterfaceType

Interface type of physical disk drive, typically IDE or SCSI.

Manufacturer

Name of the disk drive manufacturer.

MediaType

Type of media used or accessed by this device. Values are:

  • Removable media

  • Fixed hard disk

  • Unknown

Model

Manufacturer’s model number of the disk drive.

Name

Label by which the disk drive is known.

Partitions

Number of partitions on the physical disk drive that are recognized by the operating system.

PNPDeviceID

Plug and Play device identifier of the logical device.

SCSIBus

SCSI bus number of the disk drive.

SCSILogicalUnit

SCSI logical unit number (LUN) of the disk drive.

SCSIPort

SCSI port number of the disk drive.

SCSITargetId

SCSI identifier number of the disk drive.

SectorsPerTrack

Number of sectors in each track for the physical disk drive.

Signature

Unique identifier for a disk drive.

Size

Size of the disk drive. Disk drive size is calculated by multiplying the total number of cylinders, the tracks in each cylinder, the sectors in each track, and the bytes in each sector.

SystemName

Name of the computer where the disk is installed.

TotalCylinders

Total number of cylinders on the physical disk drive.

TotalHeads

Total number of heads on the disk drive.

TotalSectors

Total number of sectors on the physical disk drive.

TotalTracks

Total number of tracks on the physical disk drive.

TracksPerCylinder

Number of tracks in each cylinder on the physical disk drive.

Note

Note

The values reported for TotalCylinders, TotalHeads, TotalSectors, TotalTracks, and TracksPerCylinder are obtained through extended functions of BIOS interrupt 13h. These values might be inaccurate if the drive uses a translation scheme to support high capacity disk sizes. Consult the manufacturer for accurate drive specifications.

Scripting Steps

Listing 10.1 contains a script that enumerates the properties of all the physical drives installed on a computer. To carry out this task, the script must perform the following steps:

  1. Create a variable to specify the computer name.

  2. Use a GetObject call to connect to the Windows Management Instrumentation (WMI) namespace rootcimv2, and set the impersonation level to “impersonate.”

  3. Use the ExecQuery method to query the Win32_DiskDrive class.

    This query returns a collection consisting of all the disk drives installed on the computer.

  4. For each disk drive in the collection, echo the values of selected drive properties, including DeviceID (drive letter) and partitions, and total cylinders, heads, sectors, and tracks.

    Because the drive capabilities are returned as an array, a For Each loop is used to enumerate each capability.

Example 10.1. Enumerating Physical Disk Drive Properties

 1 strComputer = "."
 2 Set objWMIService = GetObject("winmgmts:" _
 3     & "{impersonationLevel=impersonate}!\" & strComputer & "
ootcimv2")
 4 Set colDiskDrives = objWMIService.ExecQuery _
 5     ("SELECT * FROM Win32_DiskDrive")
 6 For each objDiskDrive in colDiskDrives
 7     Wscript.Echo "Bytes Per Sector: " & _
 8         objDiskDrive.BytesPerSector
 9     For Each strCapability in objDiskDrive.Capabilities
10         Wscript.Echo "Capabilities: " & strCapability
11     Next
12     Wscript.Echo "Caption: " & objDiskDrive.Caption
13     Wscript.Echo "Device ID: " & objDiskDrive.DeviceID
14     Wscript.Echo "Index: " & objDiskDrive.Index
15     Wscript.Echo "Interface Type: " & objDiskDrive.InterfaceType
16     Wscript.Echo "Manufacturer: " & objDiskDrive.Manufacturer
17     Wscript.Echo "Media Loaded: " & objDiskDrive.MediaLoaded
18     Wscript.Echo "Media Type: " & objDiskDrive.MediaType
19     Wscript.Echo "Model: " & objDiskDrive.Model
20     Wscript.Echo "Name: " & objDiskDrive.Name
21     Wscript.Echo "Partitions: " & objDiskDrive.Partitions
22     Wscript.Echo "PNP DeviceID: " & objDiskDrive.PNPDeviceID
23     Wscript.Echo "SCSI Bus: " & objDiskDrive.SCSIBus
24     Wscript.Echo "SCSI Logical Unit: " & _
25         objDiskDrive.SCSILogicalUnit
26     Wscript.Echo "SCSI Port: " & objDiskDrive.SCSIPort
27     Wscript.Echo "SCSI TargetId: " & objDiskDrive.SCSITargetId
28     Wscript.Echo "Sectors Per Track: " & _
29         objDiskDrive.SectorsPerTrack
30     Wscript.Echo "Size: " & objDiskDrive.Size
31     Wscript.Echo "Status: " & objDiskDrive.Status
32     Wscript.Echo "Total Cylinders: " & _
33         objDiskDrive.TotalCylinders
34     Wscript.Echo "Total Heads: " & objDiskDrive.TotalHeads
35     Wscript.Echo "Total Sectors: " & objDiskDrive.TotalSectors
36     Wscript.Echo "Total Tracks: " & objDiskDrive.TotalTracks
37     Wscript.Echo "Tracks Per Cylinder: " & _
38         objDiskDrive.TracksPerCylinder
39 Next

Managing Disk Partitions

A partition is a structural division of a physical disk drive. Although a drive can contain a single partition, larger volumes are often divided into multiple partitions. This is why you might have drives C, D, and E even though your computer has only a single physical hard disk.

The Windows 2000 operating system supports the following partition types:

  • Primary partition. This is the only type of partition that can have an operating system installed. Each drive can have as many as four primary partitions, each assigned a different drive letter.

  • Extended partition. An additional partition that can be subdivided into multiple logical drives, each assigned a unique drive letter. A drive can have only one extended partition; however, you can divide this partition into multiple logical drives. This enables a disk to have more than just the four allowed primary partitions.

  • System partition. Any primary partition containing an operating system.

Partitions can tell you how a physical disk drive is actually being used. By examining the physical partitions on a disk, you can determine the following types of things:

  • How the disk has been divided into logical drives.

  • If there is unpartitioned space available on the disk. This can be determined by subtracting the size of all the partitions on a disk from the size of the disk itself.

  • If you can boot the computer from that disk (that is, does the disk contain a boot partition).

All these questions can be resolved by using the Win32_DiskPartition class. A subset of partition properties available through this class is shown in Table 10.2.

Table 10.2. Win32_DiskPartition Properties

Property

Description

BlockSize

Size (in bytes) of the blocks that form this partition.

Bootable

Boolean value indicating whether the computer can be booted from this partition.

BootPartition

Boolean value that indicates whether the partition is the active partition. The operating system uses the active partition when booting from a hard disk.

DeviceID

Unique identifier that differentiates the disk drive and partition from the rest of the system.

DiskIndex

Index number of the disk containing this partition.

Index

Index number of the partition.

Name

Label by which the object is known.

NumberOfBlocks

Total number of consecutive blocks, each block being the size of the value contained in the BlockSize property. The total size of the disk can be calculated by multiplying the value of the BlockSize property by the value of this property. If the value of BlockSize is 1, this property is the total size of the disk.

PrimaryPartition

Boolean value indicating whether this is the primary partition on the computer.

Size

Total size of the partition in bytes.

StartingOffset

Starting offset (in bytes) of the partition.

SystemName

Name of the computer where the partition is installed.

Type

Type of the partition. Values are:

  • Unused

  • 12-bit FAT

  • Xenix Type 1

  • Xenix Type 2

  • 16-bit FAT

  • Extended Partition

  • MS-DOS® V4 Huge

  • Installable File System

  • PowerPC Reference Platform

  • UNIX

  • NTFS file system

  • Win95 with Extended Int 13

  • Extended with Extended Int 13

  • Logical Disk Manager

  • Unknown

Scripting Steps

Listing 10.2 contains a script that enumerates the properties of all the disk partitions on a computer. To carry out this task, the script must perform the following steps:

  1. Create a variable to specify the computer name.

  2. Use a GetObject call to connect to the WMI namespace rootcimv2, and set the impersonation level to “impersonate.”

  3. Use the ExecQuery method to query the Win32_DiskPartition class.

    This query returns a collection consisting of all the disk partitions on all the disk drives installed on the computer.

  4. For each disk partition in the collection, echo the value of properties such as the DeviceID, the partition size, and whether the partition is bootable.

Example 10.2. Enumerating Disk Partition Properties

 1 strComputer = "."
 2 Set objWMIService = GetObject("winmgmts:" _
 3     & "{impersonationLevel=impersonate}!\" & strComputer & "
ootcimv2")
 4 Set colDiskPartitions = objWMIService.ExecQuery _
 5     ("SELECT * FROM Win32_DiskPartition")
 6 For each objPartition in colDiskPartitions
 7     Wscript.Echo "Block Size: " & objPartition.BlockSize
 8     Wscript.Echo "Bootable: " & objPartition.Bootable
 9     Wscript.Echo "Boot Partition: " & objPartition.BootPartition
10     Wscript.Echo "Description: " & objPartition.Description
11     Wscript.Echo "Device ID: " & objPartition.DeviceID
12     Wscript.Echo "Disk Index: " & objPartition.DiskIndex
13     Wscript.Echo "Index: " & objPartition.Index
14     Wscript.Echo "Name: " & objPartition.Name
15     Wscript.Echo "Number Of Blocks: " & _
16         objPartition.NumberOfBlocks
17     Wscript.Echo "Primary Partition: " & _
18         objPartition.PrimaryPartition
19     Wscript.Echo "Size: " & objPartition.Size
20     Wscript.Echo "Starting Offset: " & _
21         objPartition.StartingOffset
22     Wscript.Echo "Type: " & objPartition.Type
23 Next

Managing Logical Disk Drives

A physical disk drive is the cornerstone of any storage management system. However, after a physical disk drive has been installed, neither users nor system administrators typically deal with the hardware directly. Instead, both users and system administrators interact with the logical drives that have been created on the disk.

A logical drive is a subdivision of a partition that has been assigned its own drive letter. (It is possible to have a partition that has not been assigned a drive letter.) When you talk about drive C or drive D, you are referring to a logical drive rather than to a physical disk drive. Likewise, when you save a document to drive E, you are saving it to the logical drive. Physical disks compose the hardware that makes up a drive, including such components as heads, sectors, and cylinders. Logical drives, by contrast, have properties such as disk space, available disk space, and drive letters.

The properties of a logical drive can be retrieved using the Win32_LogicalDisk class. A subset of properties available through this class is shown in Table 10.3.

Table 10.3. Win32_LogicalDisk Properties

Property

Description

Compressed

Indicates whether the logical volume exists as a single compressed entity, such as a DoubleSpace volume. If file-based compression is supported (such as on NTFS), this property is False.

DeviceID

Unique identifier of the logical disk from other devices on the system.

DriveType

Numeric value corresponding to the type of disk drive this logical disk represents. Values are:

  • 0— Unknown

  • 1— No Root Directory

  • 2— Removable Disk

  • 3— Local Disk

  • 4— Network Drive

  • 5— Compact Disc

  • 6— RAM Disk

FileSystem

File system on the logical disk.

FreeSpace

Space available on the logical disk.

MaximumComponentLength

Maximum length of a file name component (the portion of a file name between backslashes) supported by the Win32 drive. The value can indicate that long names are supported by the specified file system.

MediaType

Type of media currently present in the logical drive. The value might not be exact for removable drives if there is no media currently in the drive. Values include (but are not limited to):

  • 0— Format is unknown

  • 1— 5.25-inch floppy disk (1.2Mb, 512 bytes/sector)

  • 2— 3.5-inch floppy disk (1.44Mb, 512 bytes/sector)

  • 3— 3.5-inch floppy disk (2.88Mb, 512 bytes/sector)

  • 4— 3.5-inch floppy disk (20.8Mb, 512 bytes/sector)

  • 11— Removable media other than floppy

  • 12— Fixed hard disk media

  • 20— 3.5-inch floppy disk (128Mb, 512 bytes/sector)

  • 21— 3.5-inch floppy disk (230Mb, 512 bytes/sector)

Name

Label by which the object is known.

Size

Size of the disk drive.

SupportsFileBasedCompression

Indicates whether the logical disk partition supports file-based compression, such as is the case with NTFS. This property is False when the Compressed property is True.

SystemName

Name of the computer where the drive is installed.

VolumeName

Volume name of the logical disk. (Maximum 32 characters.)

VolumeSerialNumber

Volume serial number of the logical disk. (Maximum 11 characters.)

Note

Note

The Win32_LogicalDisk class can be used only to enumerate the properties of local disk drives. However, you can use the Win32_MappedLogicalDisk class to enumerate the properties of mapped network drives.

Scripting Steps

Listing 10.3 contains a script that enumerates the properties of all the logical disk drives on a computer. To carry out this task, the script must perform the following steps:

  1. Create a variable to specify the computer name.

  2. Use a GetObject call to connect to the WMI namespace rootcimv2, and set the impersonation level to “impersonate.”

  3. Use the ExecQuery method to query the Win32_LogicalDisk class.

    This query returns a collection consisting of all the logical disk drives installed on the computer.

  4. For each logical disk drive in the collection, echo the drive properties, including the DeviceID, the type of file system installed on the drive, the drive type, and the amount of free space available on the drive.

Example 10.3. Enumerating Logical Disk Drive Properties

 1 strComputer = "."
 2 Set objWMIService = GetObject("winmgmts:" _
 3     & "{impersonationLevel=impersonate}!\" & strComputer & "
ootcimv2")
 4 Set colDisks = objWMIService.ExecQuery _
 5     ("SELECT * FROM Win32_LogicalDisk")
 6 For each objDisk in colDisks
 7     Wscript.Echo "Compressed: " & objDisk.Compressed
 8     Wscript.Echo "Description: " & objDisk.Description
 9     Wscript.Echo "Device ID: " & objDisk.DeviceID
10     Wscript.Echo "Drive Type: " & objDisk.DriveType
11     Wscript.Echo "FileSystem: " & objDisk.FileSystem
12     Wscript.Echo "FreeSpace: " & objDisk.FreeSpace
13     Wscript.Echo "MediaType: " & objDisk.MediaType
14     Wscript.Echo "Name: " & objDisk.Name
15     Wscript.Echo "Size: " & objDisk.Size
16     Wscript.Echo "SupportsFileBasedCompression: " & _
17         objDisk.SupportsFileBasedCompression
18     Wscript.Echo "SystemName: " & objDisk.SystemName
19     Wscript.Echo "VolumeName: " & objDisk.VolumeName
20     Wscript.Echo "VolumeSerialNumber: " & _
21         objDisk.VolumeSerialNumber
22 Next

Identifying Drives and Drive Types

Enterprise scripting often involves configuring hardware and software on remote computers; in turn, this requires you to know, in advance, the type of disk drives installed on a computer. For example, a script that installs an application on drive E works only if drive E is a hard disk. If drive E happens to represent a floppy disk or a CD-ROM drive, the script fails.

Fortunately, you can use the Win32_LogicalDisk class to verify the drive type for each disk drive installed on a computer.

Scripting Steps

Listing 10.4 contains a script that identifies the drives and drive types installed on a computer. To carry out this task, the script must perform the following steps:

  1. Create a variable to specify the computer name.

  2. Use a GetObject call to connect to the WMI namespace rootcimv2, and set the impersonation level to “impersonate.”

  3. Use the ExecQuery method to query the Win32_LogicalDisk class.

    This query returns a collection consisting of all the logical disk drives (including hard disks, floppy disks, and compact discs) installed on the computer.

  4. For each logical disk drive in the collection, echo the DeviceID (the drive letter) and the drive type.

    The Win32_LogicalDisk class returns the value of the DriveType property as an integer. Therefore, a series of Select Case statements is used to convert the value to a text string. For example, if the DriveType is equal to 3, the string “Local hard disk” is echoed to the screen.

Example 10.4. Identifying Drives and Drive Types

 1 strComputer = "."
 2 Set objWMIService = GetObject("winmgmts:" _
 3     & "{impersonationLevel=impersonate}!\" & strComputer & "
ootcimv2")
 4 Set colDisks = objWMIService.ExecQuery _
 5     ("SELECT * FROM Win32_LogicalDisk")
 6 For Each objDisk in colDisks
 7     Wscript.Echo "DeviceID: "& objDisk.DeviceID
 8     Select Case objDisk.DriveType
 9         Case 1
10             Wscript.Echo "No root directory."
11         Case 2
12             Wscript.Echo "DriveType: Removable drive."
13         Case 3
14             Wscript.Echo "DriveType: Local hard disk."
15         Case 4
16             Wscript.Echo "DriveType: Network disk."
17         Case 5
18             Wscript.Echo "DriveType: Compact disk."
19         Case 6
20             Wscript.Echo "DriveType: RAM disk."
21         Case Else
22             Wscript.Echo "Drive type could not be determined."
23     End Select
24 Next

Changing Logical Disk Volume Names

Using drive letters as the sole means of identifying a logical drive can cause confusion. Drive letters can vary not only from computer to computer (depending on how many drives are installed on each computer), but can also vary over time on an individual computer. For example, a computer might have a removable drive connected, and thus have drives A, B, C, D, and E. Later, the drive might be disconnected and the computer would then have drives A, B, C, and D.

One way to work around this problem is to use volume names (also referred to as volume labels) to help differentiate logical drives. For example, a computer might have the following logical drives:

  • Drive C (system drive)

  • Drive D (applications drive)

  • Drive E (data drive)

Instead of referring to these as drives C, D, and E, you can give them the volume names System, Applications, and Data. This makes it easier to identify the individual drives, particularly if other computers in the organization are configured in a different manner, for example, with drive D hosting data and drive E hosting applications. Using a consistent naming scheme across the organization helps facilitate administration and makes it easier for users who might use a different computer each time they log on.

You can use the Win32_LogicalDisk class to rename volumes on a computer. When renaming volumes, consider the following issues:

  • Volume names are limited to 32 characters.

  • You cannot change the volume label on a removable drive.

  • Volume names do not have to be unique on a computer. Therefore, if you specify the incorrect drive when using scripts to change volume names, you could inadvertently give every volume on the computer the same name.

Scripting Steps

Listing 10.5 contains a script that changes the name of a volume. To carry out this task, the script must perform the following steps:

  1. Create a variable to specify the computer name.

  2. Use a GetObject call to connect to the WMI namespace rootcimv2 and set the impersonation level to “impersonate.”

  3. Use the ExecQuery method to query the Win32_DiskDrive class.

    To ensure that only drive C receives the name change, a Where clause is included to limit data retrieval to those drives with a DeviceID of C. The query thus returns a collection consisting of only those logical disk drives with a DeviceID of C.

  4. For the only disk drive in the collection, set the VolumeName property to “Finance Volume”.

  5. Use the Put_ method to apply the changes and rename the volume.

Example 10.5. Changing Volume Names

1 strComputer = "."
2 Set objWMIService = GetObject("winmgmts:" _
3     & "{impersonationLevel=impersonate}!\" & strComputer & "
ootcimv2")
4 Set colDrives = objWMIService.ExecQuery _
5     ("SELECT * FROM Win32_LogicalDisk WHERE DeviceID = 'C:'")
6 For Each objDrive in colDrives
7     objDrive.VolumeName = "Finance Volume"
8     objDrive.Put_
9 Next

Managing Disk Space

In storage management, it is crucial to ensure that there is enough disk space available to meet user needs. Users need room to store their documents, and you should not allow servers to fail because of an out-of-disk-space error. In addition, tracking disk space usage is important in planning for future needs.

Enumerating Disk Space on a Computer

You can use the Win32_LogicalDisk class to enumerate the available disk space on any computer in your organization.

Scripting Steps

Listing 10.6 contains a script that enumerates the free space on all the hard disk drives on a computer. To carry out this task, the script must perform the following steps:

  1. Create a constant named LOCAL_HARD_DISK and set the value to 3. This constant limits data retrieval to local hard disks (DriveType = 3).

  2. Create a variable to specify the computer name.

  3. Use a GetObject call to connect to the WMI namespace rootcimv2, and set the impersonation level to “impersonate.”

  4. Use the ExecQuery method to query the Win32_LogicalDisk class.

    Because free space is typically a concern only on local hard disks (as opposed to floppy disks or compact discs), a Where clause is included to limit data retrieval to local hard disks (DriveType = LOCAL_HARD_DISK). This results in a collection of all the hard disks installed on the computer.

  5. For each logical disk drive in the collection, echo the DeviceID and the value of the FreeSpace property.

Example 10.6. Enumerating Free Disk Space

 1 Const HARD_DISK = 3
 2 strComputer = "."
 3 Set objWMIService = GetObject("winmgmts:" _
 4     & "{impersonationLevel=impersonate}!\" & strComputer & "
ootcimv2")
 5 Set colDisks = objWMIService.ExecQuery _
 6     ("SELECT * FROM Win32_LogicalDisk WHERE DriveType = " _
 7         & HARD_DISK & "")
 8 For Each objDisk in colDisks
 9     Wscript.Echo "Device ID: " & objDisk.DeviceID
10     Wscript.Echo "Free Disk Space: " & objDisk.FreeSpace
11 Next

Enumerating Disk Space by User

Tracking disk space use by user is an important administrative task. It helps ensure that users are allocated sufficient disk space, and it also ensures that no single user takes up a disproportionate share of the available space.

If you use NTFS disk quotas, NTFS tracks the amount of disk space consumed by each user on a volume. To gain a better understanding of how disk space is being apportioned on a computer, you can enable disk quotas on a volume and allow NTFS to enumerate disk space use by user. After quotas have been enabled, you can retrieve the disk space use enumeration by using the DiskQuotaControl Automation object. This use of this object is explained in more detail in the “Managing Disk Quotas on the NTFS File System” section of this chapter.

Tip

Tip

Enabling disk quotas does not mean you have to limit the amount of disk space available to users. If you are primarily concerned with assessing disk space use, enable quotas but allocate each user an unlimited amount of disk space. Alternatively, you can enable quotas, retrieve an NTFS-generated disk space use report, and then disable the quotas again.

Scripting Steps

Listing 10.7 contains a script that uses disk quotas to enumerate disk space use by user. To carry out this task, the script must perform the following steps:

  1. Create an instance of the DiskQuota1 object.

  2. Use the Initialize method to indicate that the new quota entry should be added to drive C. This will return a collection of all users with disk quota entries on drive C.

    The Initialize method requires the following two parameters:

    • The drive letter of the drive where quotas are being enumerated (in this case, C).

    • The value True, indicating that the drive should be initialized for read/write access. By setting this value to False, you can enumerate disk quota entries on the volume but you cannot make any changes (read-only).

  3. For each user in the collection of disk quota entries, echo the values of the LogonName and QuotaUsed properties.

Example 10.7. Using Disk Quotas to Enumerate Disk Space by User

1 Set colDiskQuotas = CreateObject("Microsoft.DiskQuota.1")
2 colDiskQuotas.Initialize "C:", True
3 For Each objUser in colDiskQuotas
4     Wscript.Echo "Logon name: " & objUser.LogonName
5     Wscript.Echo "Quota used: " & objUser.QuotaUsed
6 Next

Monitoring Free Disk Space in Real-Time

If disk space is used at a fairly predictable rate, you do not have to constantly monitor the free space on a disk. Instead, you might check free space once or twice a day and then use that data to predict when available space might become scarce.

However, disk use might not always be predictable. On some servers, the amount of data added to the drive might vary widely from day to day. If these servers carry out critical functions in your organization, you might prefer to be notified immediately if disk space runs low. Instead of finding out tomorrow morning that the mail server is almost out of disk space, you might want to be informed the moment available space drops below a specified level.

To receive these immediate notifications, you can use a temporary event consumer to monitor available disk space. You can specify a threshold, such as 100 megabytes (MB) of free space, and receive immediate notification if available disk space on the computer falls below that threshold.

Scripting Steps

Listing 10.8 contains a script that monitors the free disk space on a computer. To carry out this task, the script must perform the following steps:

  1. Create a constant named LOCAL_HARD_DISK and set the value to 3.

    This ensures that the query responds only to changes to the hard disks installed on the computer.

  2. Create a variable to specify the computer name.

  3. Use a GetObject call to connect to the WMI namespace rootcimv2, and set the impersonation level to “impersonate.”

  4. Use the ExecNotificationQuery method to register for event notifications. In this case, notification is requested any time there is a modification to the Win32_LogicalDisk class. The Within 30 clause specifies that events will be checked every 30 seconds, which means you will receive a notice no later than 30 seconds after a disk runs low on disk space.

  5. Create a Do loop to allow for continuous monitoring.

  6. Each time notification is received (by means of the NextEvent method), check to see if the event involves a hard disk. If it does, proceed to step 7. If it does not, proceed to step 8.

  7. If the event involved a change to a hard disk and the available space on the disk is now less than 100,000,000 bytes, echo the message “Hard disk space has fallen below 100,000,000 bytes.” In a production-level script, of course, you might send an e-mail or a network alert rather than simply echo a message to the screen.

  8. Loop around and continue monitoring.

Example 10.8. Monitoring Free Disk Space

 1 Const LOCAL_HARD_DISK = 3
 2 strComputer = "."
 3 Set objWMIService = GetObject("winmgmts:" _
 4     & "{impersonationLevel=impersonate}!\" & strComputer & "
ootcimv2")
 5 Set colMonitoredDisks = objWMIService.ExecNotificationQuery _
 6     ("Select * from __instancemodificationevent within 30 where " _
 7         & "TargetInstance isa 'Win32_LogicalDisk'")
 8 i = 0
 9 Do While i = 0
10     Set objDiskChange = colMonitoredDisks.NextEvent
11     If objDiskChange.TargetInstance.DriveType = LOCAL_HARD_DISK Then
12         If objDiskChange.TargetInstance.Size < 100000000 Then
13             Wscript.Echo "Hard disk space is below 100000000 bytes."
14         End If
15     End If
16 Loop

Managing Disk Quotas

Storing user data on central file servers offers a number of conveniences: the data is easy to locate, easy to transfer to another user, and easy to back up. However, centralized data storage does pose one problem: How do you prevent a single user from using up all the available disk space? As more and more users have gained access to the Internet, this problem has become even more severe, with many users downloading music and video files, expecting to store that data on the central file server. Disk quotas, introduced in the Windows 2000 operating systems, provide a way for administrators to monitor and control disk space use on servers.

With disk quotas, you can set limits on a user’s disk space. If a user exceeds his or her quota, you can record this fact in the System event log, or you can set the system to deny the user the ability to store additional information. You can also customize quotas; this allows you to allocate larger amounts of disk space to users (such as graphic artists) who require additional storage.

Disk quotas also enable you to:

  • Track disk use on a per-user, per-volume basis, and thus better plan for storage allocation.

  • Manage storage resources more effectively by requiring users to periodically delete unneeded files.

  • Decrease backup and restoration times by limiting the amount of data that needs to be backed up and restored.

Managing Disk Quotas on the NTFS File System

Disk quotas are an integral part of the NTFS file system. When a file or a folder is created on a volume formatted with NTFS, that item is assigned an owner (typically the user who created the item). NTFS obtains the user ID of the file owner and stores that information in the file or folder’s Standard Information attribute. This attribute tallies all the disk space allocated to the file or folder. NTFS then locates the quota entry for that user and determines whether the new allocation of disk space causes the user to exceed the assigned quota. If it does, NTFS then takes the appropriate steps, which can include logging an entry in the System event log or preventing the user from creating the file or folder. As the file or folder changes size, NTFS updates the quota control entry to reflect the total disk space used by the user.

Disk quotas are not configured on a computer-wide basis, but are instead tied to individual NTFS volumes. Each drive has separate quota settings, and the actions you take on one volume do not affect the other volumes.

For example, a computer might have a single hard disk divided into three volumes: drives C, D, and E. Each of these drives has separate quota settings. You could enable disk quotas on drives C and D, but disable them on drive E. Likewise, you could grant users 50 MB of disk space on drive C and 100 MB of disk space on drive D.

When managing disk quotas on a computer, the actions you take on one volume do not affect the other volumes in any way. If you allocate User A 50 MB of disk space on drive C, this does not also give User A 50 MB of disk space on drives D and E. If you disable disk quotas on drive D, quotas remain enabled on drives C and E.

In addition to allocating disk space, you can specify a quota warning level, the amount of disk space use that triggers an alert (an event recorded in the System event log informing you that a user is nearing the quota). You can also determine which of the following actions the system takes if a user exceeds the quota:

  • Take no action at all.

  • Record an event in the System event log.

  • Deny the user the right to store additional data until he or she has removed enough files to get back under the quota.

The Windows 2000 operating systems include an Automation object — the DiskQuotaControl object — that can be used to create and manage disk quotas on a volume. The one limitation of this object is that it must be used locally. You must run the script on the computer where the disk quota entry is created, and you cannot use the DiskQuotaControl object to create quota entries or manage quota settings on remote volumes.

Note

Note

You can use the WshController object to run the script on a remote computer, and thus create quota entries on a remote computer. For more information about the WshController object, see “WSH Primer” in this book.

In addition, the DiskQuotaControl object can retrieve information only for one volume at a time. After creating an instance of the object, you must use the Initialize method and pass it the drive letter of the volume you want to work with. (You cannot return a collection consisting of all the volumes on the computer and then manage the quota settings for each of these volumes all at once.) For example, the following code sample allows you to work with disk quotas on drive C:

Set colDiskQuotas = CreateObject("Microsoft.DiskQuota.1")
colDiskQuotas.Initialize "C:", True

To work with a second volume (such as drive D), you will have to call the Initialize method a second time, passing the drive letter of the new volume.

colDiskQuotas.Initialize "D:", True

After calling this method, you will be able to work only with disk quotas on drive D. To work with quotas on drive C again, you would need to call the Initialize method a third time, once again passing the method the drive letter for drive C.

Enumerating Disk Quota Settings

Keeping track of the quota settings on all volumes on a computer is an important administrative task. You need to know whether disk quotas have been enabled, and you need to know both the default quota and the actions the system takes if a user exceeds the quota. This information can be retrieved by using the DiskQuotaControl. Table 10.4 lists a subset of key properties for this object. All of these properties are read/write, meaning that scripts can be used to both configure and enumerate these settings.

Table 10.4. DiskQuotaControl Properties

Property

Description

DefaultQuotaLimit

Default limit (in bytes) set for quotas on this particular volume. If the DefaultQuotaLimit is -1, no quota limit has been set.

DefaultQuotaThreshold

Default warning limit (in bytes) set for quotas on this particular volume. If the DefaultQuotaThreshold is -1, no warning limit has been set.

LogQuotaLimit

Indicates whether or not events are written to the event log if users exceed their quotas.

QuotaState

Level of quota management set for this particular volume. Values are:

  • 0— Quota management is not enabled on this volume.

  • 1— Quotas are enabled on this volume, but are not enforced. Users are allowed to exceed their quota limit.

  • 2— Quotas are tracked and enforced on this volume. Users are not allowed to exceed their quota limit.

LogQuotaThreshold

Indicates that events are written to the event log when the warning limit is exceeded.

Scripting Steps

Listing 10.9 contains a script that enumerates the disk quota settings for drive C on a computer. To carry out this task, the script must perform the following steps:

  1. Create an instance of the DiskQuota1 object.

  2. Use the Initialize method to indicate that quota settings should be enumerated for drive C.

    The Initialize method requires the following two parameters:

    • The drive letter of the drive (in this case, C).

    • The value True, indicating that the drive should be initialized for read/write access. By setting this value to False, you can enumerate disk quota settings on the volume but you cannot make any changes (read-only).

  3. Echo the values of the disk quota settings.

    Because the quota state is returned as an integer (0 if quotas are disabled, 1 if quotas are enabled but not enforced, and 2 if quotas are enabled and enforced), an If Then construct is used to echo the appropriate message (for example, “Quota state: Disabled” if the value of the QuotaState property is 0).

Example 10.9. Enumerating Disk Quota Settings

 1 Set colDiskQuotas = CreateObject("Microsoft.DiskQuota.1")
 2 colDiskQuotas.Initialize "C:", True
 3 If colDiskQuotas.QuotaState = 2 Then
 4     Wscript.Echo "Quota state: Enabled and enforced"
 5 ElseIf colDiskQuotas.QuotaState = 1 Then
 6     Wscript.Echo "Quota state: Enabled but not enforced"
 7 Else
 8     Wscript.Echo "Quota state: Disabled"
 9 End If
10 Wscript.Echo "Default quota limit: " & colDiskQuotas.DefaultQuotaLimit
11 Wscript.Echo "Default warning limit: " & _
12     colDiskQuotas.DefaultQuotaThreshold
13 Wscript.Echo "Record quota violations in event log: " & _
14     colDiskQuotas.LogQuotaLimit
15 Wscript.Echo "Record warnings in event log: " & _
16     colDiskQuotas.LogQuotaThreshold

Enabling and Disabling Disk Quotas

You can enable and disable disk quotas on a volume by toggling the value of the DiskQuotaControl QuotaState property. When the value of the QuotaState property is set to 2, quotas are enabled and enforced; users who exceed their quota limit will not be able to save additional data to the drive. When the value of the QuotaState property is set to 1, quotas will be enabled but not enforced. This means that users who exceed their quota limit will still be able to save data to the drive. When the value of the QuotaState property is set to 0, quotas are disabled.

When you disable quotas on a volume, you do not discard previous quota information. Instead, you simply stop the Windows 2000 operating system from enforcing disk quotas and tracking disk space usage.

For example, suppose you have a volume with the quota entries shown in Table 10.5.

Table 10.5. Sample Disk Quota Entries

Name

Quota Limit

Warning Level

KMeyer

100 MB

90 MB

PAckerman

200 MB

180 MB

RWilliams

400 MB

350 MB

If you disable disk quotas on this volume, these quota entries are not deleted. If you later decide to re-enable disk quotas, each of the entries shown in Table 10.5 is restored, along with the appropriate quota limit and warning level.

Scripting Steps

Listing 10.10 contains a script that enables disk quotas for drive C on a computer. To carry out this task, the script must perform the following steps:

  1. Create a constant named ENABLE_QUOTAS and set the value to 2. This constant will be used to enable and enforce disk quotas on the volume.

  2. Create an instance of the DiskQuota1 object.

  3. Use the Initialize method to indicate that disk quotas should be enabled on drive C.

    The Initialize method requires the following two parameters:

    • The drive letter of the drive where disk quotas are being enabled (in this case, C).

    • The value True, indicating that the drive should be initialized for read/write access.

  4. Set the value of the QuotaState property to 2, using the constant ENABLE_QUOTAS.

Example 10.10. Enabling Disk Quotas

1 Const ENABLE_QUOTAS = 2
2 Set colDiskQuotas = CreateObject("Microsoft.DiskQuota.1")
3 colDiskQuotas.Initialize "C:", True
4 colDiskQuotas.QuotaState = ENABLE_QUOTAS

Configuring Default Disk Quota Settings

As circumstances change, you might need to adjust the default quota settings on a volume. For example, you might initially give each user up to 100 MB of storage space on a volume. If your department hires new employees, you might have to lower this quota to ensure that all these additional users can store items on the disk. Alternatively, by purchasing a second file server for user data, you might be able to divide your users between the two servers, thus providing them with additional disk space.

Either way, you can use the DiskQuotaControl to change the default quota values for a volume. In addition to changing the quota and warning levels, you can also specify whether you want to record quota violations in the event log.

When you change the default disk quota settings, these new values apply only to new users; they are not applied to users who already have disk quota entries on the volume. For example, suppose you have a volume with the quota entries shown in Table 10.6.

Table 10.6. Sample Disk Quota Entries

Name

Quota Limit

Warning Level

KMeyer

100 MB

90 MB

PAckerman

200 MB

180 MB

RWilliams

400 MB

350 MB

If you change the default quota settings to a quota of 50 MB and a warning limit of 40 MB, those values are applied to any new user who saves a file or folder to the column. However, the quota settings for the three users shown in Table 10.6 do not change. The only way to change the quota settings for existing users is to individually bind to each quota entry and then change the value. For more information about this process, see “Modifying a Disk Quota Entry” later in this chapter.

Scripting Steps

Listing 10.11 contains a script that configures disk quota settings on a computer. To carry out this task, the script must perform the following steps:

  1. Create an instance of the DiskQuota1 object.

  2. Use the Initialize method to indicate that the default quota settings are being changed for drive C.

    The Initialize method requires the following two parameters:

    • The drive letter of the drive where the quota settings are being changed (in this case, C).

    • The value True, indicating that the drive should be initialized for read/write access. By setting this value to False, you can enumerate disk quota settings on the volume but you cannot make any changes (read-only).

  3. Set the value of the DefaultQuotaLimit property to 10,000,000. This limits users to approximately 10 MB of disk space.

Example 10.11. Configuring Disk Quota Settings

1 Set colDiskQuotas = CreateObject("Microsoft.DiskQuota.1")
2 colDiskQuotas.Initialize "C:", True
3 colDiskQuotas.DefaultQuotaLimit = 10000000

Managing Disk Quotas for Individual Users

When you enable disk quotas on a volume and specify a quota, every user who stores data on that volume is automatically limited to the amount of disk space specified by the quota. For example, suppose you set a quota of 50 MB. As soon as users save their first bit of data to the volume, they are automatically assigned a quota of 50 MB. If you have users who require more (or less) than 50 MB of disk space, you can create individual quota entries for those users.

Determining Quota Limits

Disk quotas are based on the files and folders owned by a user. When determining disk quotas, consider the following factors:

  • Disk quotas are based on file ownership. If a user modifies a file owned by another user, the disk space allocated for that file is charged to the file owner. This will typically be the user who initially created the file. However, some applications change the file owner based on the last person to modify the file. If a file is owned by User A and then modified by User B, some applications transfer ownership to User B. In that case, disk space is charged to User B.

  • Disk quotas are based on the uncompressed size of a file. Compressing a file does not change the amount of disk space charged to the file owner.

  • When disk quotas are enforced, the quotas change the amount of volume free space reported to a user. For example, suppose a user has been given a quota of 1 gigabyte (GB) on a volume that has 50 GB of free space. When the user checks free space on the volume, it reports only 1 GB minus whatever disk space is already used. The user does not know that there are actually 50 GB of free space available on the volume.

  • By default, administrators have an unlimited amount of disk space on a volume. When you enable disk quotas, the Administrators group is automatically added to the quota table and given unlimited disk space. Do not change this default. If you remove the Administrators group or limit the disk space allocated to this group, you might limit the ability of administrators to manage the system.

Note

Note

The Administrators group owns all files created by any administrator.

Enumerating Disk Quotas

The DiskQuotaControl enables you to enumerate the quota entries for a particular volume. You can use this object to determine the quota and warning limit established for each user, the amount of disk space currently charged to the user, and whether the user has exceeded his or her quota level. Key user-related properties of the DiskQuotaControl are shown in Table 10.7.

Table 10.7. DiskQuotaControl Properties Related to Individual Users

Property

Description

AccountStatus

Status of the user account. Values are:

  • 0— Account is valid.

  • 1— Account information is unavailable.

  • 2— Account has been deleted.

  • 3— Account is invalid.

  • 4— Account cannot be found.

  • 5— Account information cannot be resolved.

DisplayName

Full name of the user associated with the quota entry (for example, Ken Myer). Values will be displayed only for local user accounts.

ID

Unique ID number assigned to the quota entry.

LogonName

User name of the user associated with the quota entry (for example, kmyer).

QuotaLimit

Quota limit (in bytes) set for this particular user. A value of -1 means that no limit has been set for the user.

QuotaThreshold

Warning limit (in bytes) set for this particular user. A value of -1 means that no limit has been set for the user.

QuotaUsed

Current number of bytes currently in use by this particular user.

Scripting Steps

Listing 10.12 contains a script that enumerates the disk quota entries on a computer. To carry out this task, the script must perform the following steps:

  1. Create an instance of the DiskQuota1 object.

  2. Use the Initialize method to indicate that the new quota entry should be added to drive C. This returns a collection of all users with disk quota entries on drive C.

    The Initialize method requires the following two parameters:

    • The drive letter of the drive where quotas are being enumerated (in this case, C).

    • The value True, indicating that the drive should be initialized for read/write access. By setting this value to False, you can enumerate disk quota entries on the volume but you cannot make any changes (read-only).

  3. For each user in the collection of disk quota entries, echo the values of the LogonName, QuotaLimit, QuotaThreshold, and QuotaUsed properties.

Example 10.12. Enumerating Disk Quotas

1 Set colDiskQuotas = CreateObject("Microsoft.DiskQuota.1")
2 colDiskQuotas.Initialize "C:", True
3 For Each objUser in colDiskQuotas
4     Wscript.Echo "Logon name: " & objUser.LogonName
5     Wscript.Echo "Quota limit: " & objUser.QuotaLimit
6     Wscript.Echo "Quota threshold: " & objUser.QuotaThreshold
7     Wscript.Echo "Quota used: " & objUser.QuotaUsed
8 Next

Issuing Disk Quota Alerts

When a user reaches his or her quota warning level, an event is recorded in the System event log on the computer where the quota violation occurred. However, no notice of any kind is issued to the user. Users do not know that they are reaching their quota limit unless an administrator periodically scans the event log for quota violations and then issues a warning. Without such notices, users will find out they have reached their quota limit only when they attempt to save a file and are denied access because they have run out of disk space.

Because of this, you might want to create a script that periodically checks to see which users, if any, are over their warning limit and then issues an alert (such as an e-mail message).

Adding a New Disk Quota Entry

When disk quotas are enabled on a volume, the default quota and the default warning limit are automatically applied to any users who already have files stored on that volume. If a new user stores a file on the volume, a quota entry is created that grants that user the same default values. Administrators do not have to manually create new quota entries each time a new user saves a file on the volume.

However, you might want to assign some users a quota limit different from the default value. For example, you might want to allot graphic artists more disk space. If so, you can wait until a graphic artist has saved a file on the volume (and thus been assigned the default quotas) and then change his or her quota. Alternatively, you can create quota entries for each graphic artist in advance, before the user has saved any files to the volume, and give each of these users the desired quota value.

Scripting Steps

Listing 10.13 contains a script that adds a new entry to the disk quotas on a computer. To carry out this task, the script must perform the following steps:

  1. Create an instance of the DiskQuota1 object.

  2. Use the Initialize method to indicate that the new quota entry should be added to drive C.

    The Initialize method requires the following two parameters:

    • The drive letter of the drive where the quota is added (in this case, C).

    • The value True, indicating that the drive should be initialized for read/write access. By setting this value to False, you can enumerate disk quota entries on the volume but you cannot make any changes (read-only).

  3. Use the AddUser method to create a quota entry for user jsmith from the fabrikam domain. If you are adding a quota entry for a domain user account, be sure to include the name of the domain (for example, fabrikamjsmith). If you are adding a quota entry for a local user account, be sure to include the name of the computer where the entry is being added (for example, atl-dc-01jsmith).

  4. Use the Sleep method to pause the script for 5 seconds. This ensures that the new quota entry will be added before you attempt to connect to the new entry and modify the quota limit.

  5. Use the FindUser method to query the quota entry for jsmith from the fabrikam domain.

  6. Set the QuotaLimit for user jsmith from the fabrikam domain to 50,000,000 bytes.

Example 10.13. Adding a New Disk Quota Entry

1 Set colDiskQuotas = CreateObject("Microsoft.DiskQuota.1")
2 colDiskQuotas.Initialize "C:", True
3 Set objUser = colDiskQuotas.AddUser("fabrikamjsmith")
4 Wscript.Sleep 5000
5 Set objUser = colDiskQuotas.FindUser("fabrikamjsmith")
6 objUser.QuotaLimit = 50000000

Modifying a Disk Quota Entry

You can also use the DiskQuotaControl object to modify the quotas assigned to an existing user. By binding to the quota entry for a user, you can change both the maximum disk space allocated to that user (QuotaLimit) and the disk space usage that triggers a quota warning (QuotaThreshold).

Scripting Steps

Listing 10.14 contains a script that modifies the disk quota for a user. To carry out this task, the script must perform the following steps:

  1. Create an instance of the DiskQuota1 object.

  2. Use the Initialize method to indicate that the quota entry to be modified is on drive C.

    The Initialize method requires the following two parameters:

    • The drive letter of the drive where the quota resides (in this case, C).

    • The value True, indicating that the drive should be initialized for read/write access. By setting this value to False (read-only), you can enumerate disk quota entries on the volume but you cannot make any changes.

  3. Use the FindUser method to query the quota entry for jsmith from the fabrikam domain.

  4. Set the QuotaThreshold for user jsmith from the fabrikam domain to 90,000,000 bytes, and set the QuotaLimit to 100,000,000 bytes.

Example 10.14. Modifying a Disk Quota Entry

1 Set colDiskQuotas = CreateObject("Microsoft.DiskQuota.1")
2 colDiskQuotas.Initialize "C:", True
3 Set objUser = colDiskQuotas.FindUser("fabrikamjsmith")
4 objUser.QuotaThreshold = 90000000
5 objUser.QuotaLimit = 100000000

Deleting a Disk Quota Entry

The DiskQuotaControl object includes a DeleteUser method that you can use to delete quota entries from a quota table. This method is useful for keeping your quota tables up to date. For example, if a user leaves the organization, you can remove his or her quota entry to ensure that the quota table reflects only valid users and user accounts.

It is important to note that deleting a quota entry does not deny the user the right to store files on the volume. If you delete a user’s quota entry and the user attempts to store something on the volume, a brand-new quota entry is created for the user. You need to use NTFS permissions to deny a user permission to store files on a volume.

In addition, you cannot delete quota entries from the disk quota table as long as the user still owns any files or folders on the volume. If a user leaves the organization, you must perform one of the following actions before you can delete a user’s quota entry:

  • Move all the files or folders owned by the user to another volume.

  • Take ownership of all the files or folders owned by the user.

Scripting Steps

Listing 10.15 contains a script that deletes the disk quota entry for a user. To carry out this task, the script must perform the following steps:

  1. Create an instance of the DiskQuota1 object.

  2. Use the Initialize method to indicate that the quota entry to be deleted is on drive C.

    The Initialize method requires the following two parameters:

    • The drive letter of the drive where the quota resides (in this case, C).

    • The value True, indicating that the drive should be initialized for read/write access. Setting this value to False allows you to enumerate disk quota entries on the volume but does not allow you to change the disk quota entries.

  3. Use the FindUser method to query the quota entry for a user, (in this case, jsmith from the fabrikam domain).

  4. Use the DeleteUser method to delete the quota entry for jsmith from the fabrikam domain.

Example 10.15. Deleting a Disk Quota Entry

1 Set colDiskQuotas = CreateObject("Microsoft.DiskQuota.1")
2 colDiskQuotas.Initialize "C:", True
3 Set objUser = colDiskQuotas.FindUser("fabrikamjsmith")
4 colDiskQuotas.DeleteUser(objUser)

Managing File Systems

Disk drives can be likened to the mailrooms found in large organizations. These mailrooms typically consist of a huge array of mailboxes, each designed to hold information, such as a letter, a package, or an internal memo. For the most part, these mailboxes are identical, and nothing prevents you from storing a letter in mailbox A, mailbox B, or mailbox C. However, a mailroom must be organized in a way that makes it quick and easy to retrieve information. This is typically done by grouping mailboxes by employee name, by department, or by room number. This organization helps ensure that mailbox A contains only the mail intended for user A.

Disk drives are similar to an array of mailboxes. They provide a way to store information, but they do not impose any organizing scheme upon that information. If you want to quickly and easily retrieve information from a disk drive, you must use a file system, a component of the operating system that organizes and retrieves stored data.

Just as mailrooms can be set up differently, file systems can also be organized differently. For example, Windows operating systems support a number of different file systems, including NTFS, file allocation table (FAT), and FAT32. Each of these file systems has different capabilities; you must manage computers running the NTFS file system differently than you manage computers running the FAT file system. With Windows 2000, you can use scripts to help identify the file system in use on a computer and, at least in the case of NTFS, configure the properties of that file system to best fit the needs of that computer.

Identifying the File System Type

The type of file system installed on a volume determines the things you can and cannot do with that volume. For example, if you have a dual-boot computer and need to access a volume from Microsoft® Windows® Millennium Edition, you must format that volume using either FAT or FAT32; Windows Millennium Edition cannot access NTFS volumes. By contrast, if you need to enable disk quotas or use file and folder permissions, you must do this on an NTFS volume; neither capability is supported by FAT or FAT32.

The Win32_LogicalDisk class can be used to identify the file system installed on any logical drive on a computer.

Note

Note

The Win32_LogicalDisk class does not distinguish between the versions of NTFS found in Microsoft® Windows NT® 4.0 or Windows 2000. Instead, it reports both as “NTFS,” even though the versions differ in capabilities. In these cases, you might want to identify the operating system version as well as the type of file system installed. For more information about identifying the operating system version, see “Computer Assets” in this book.

Scripting Steps

Listing 10.16 contains a script that identifies the file system used on each logical disk on a computer. To carry out this task, the script must perform the following steps:

  1. Create a variable to specify the computer name.

  2. Use a GetObject call to connect to the WMI namespace rootcimv2, and set the impersonation level to “impersonate.”

  3. Use the ExecQuery method to query the Win32_LogicalDisk class.

    This returns a collection of all the logical disk drives installed on the computer.

  4. For each logical disk drive in the collection, echo the device ID and the type of file system installed on the drive.

Example 10.16. Identifying the File System Type

1 strComputer = "."
2 Set objWMIService = GetObject("winmgmts:" _
3     & "{impersonationLevel=impersonate}!\" & strComputer & "
ootcimv2")
4 Set colDisks = objWMIService.ExecQuery _
5     ("SELECT * FROM Win32_LogicalDisk")
6 For Each objDisk in colDisks
7     Wscript.Echo "Device ID: " & objDisk.DeviceID
8     Wscript.Echo "File System: " & objDisk.FileSystem
9 Next

Enumerating NTFS Properties

NTFS properties play an important role in determining the optimal configuration of your file system. Despite that, few system administrators are aware of how these properties have been configured, largely because no graphical user tool for viewing NTFS properties is provided with the operating system. In fact, you can only view and configure these properties through the registry. You can find the registry entries that configure NTFS properties, shown in Table 10.8, in the subkey HKEY_LOCAL_MACHINESystemCurrentControlSetControlFileSystem.

Table 10.8. Registry Entries for NTFS Properties

Registry Entry

Description

NtfsDisable8dot3NameCreation

Specifies whether NTFS automatically generates an 8.3 file name for each new file created on the volume. If MS-DOS or Microsoft® Windows® 3.x clients do not need access to the volume, enabling this property can speed up file system activity.

NtfsAllowExtendedCharacterIn8Dot3Name

Specifies whether you can use extended characters in short file names.

NtfsMftZoneReservation

Specifies the relative size of the master file table (MFT).

NtfsDisableLastAccessUpdate

Specifies whether NTFS updates the last-access timestamp on each directory when it lists the directories on an NTFS volume.

This property is designed to prevent the NTFS log buffer in physical memory from becoming filled with timestamp update records. If you have an NTFS volume with a very large number of directories (in excess of 70,000) and the operating system does not respond quickly to dir commands, adding this entry to the registry might make directories list faster.

Win31FileSystem

Specifies whether the FAT file system uses long file names and extended timestamps. This entry limits the files stored on FAT volumes to using only features found in the FAT file system used in Windows 3.1 and earlier versions. Changing this entry does not change any files, but it does change how the FAT file system displays and manages the files.

Note

Note

Not all of these entries are present by default. Depending on your operating system and your setup, you might have to create these entries. For information on adding entries to the registry, see “Registry” in this book.

You can use a tool such as Regedit.exe to view these registry entries and their values. Alternatively, you can retrieve this same information using a script. Scripts allow data retrieval to be carried out in an automated fashion. Furthermore, using WMI in the script allows you to retrieve these properties from remote computers as well as from the local computer.

Caution

Caution

Changing the registry with a script can easily propagate errors. The scripting tools bypass safeguards, allowing settings that can damage your system, or even require you to reinstall Windows. Before scripting changes to the registry, test your script thoroughly and back up the registry on every computer on which you will make changes. For more information about scripting changes to the registry, see the Registry Reference on the Microsoft Windows 2000 Server Resource Kit companion CD or at http://www.microsoft.com/reskit.

Scripting Steps

Listing 10.17 contains a script that enumerates the properties of the NTFS file system that a computer uses. To carry out this task, the script must perform the following steps:

  1. Create a constant named HKEY_LOCAL_MACHINE and set the value to &H80000002. This value is required by the Standard Registry Provider when connecting to the HKEY_LOCAL_MACHINE portion of the registry. (For more information about using the WMI Standard Registry Provider, see “Registry” in this book.)

  2. Create a variable to specify the computer name.

  3. Use a GetObject call to connect to the WMI namespace rootdefault:StdRegProv on the computer, and set the impersonation level to “impersonate.”

  4. Set the variable strValueName to the path within the HKEY_LOCAL_MACHINE portion of the registry. For each value being retrieved, the path is SystemCurrentControlSetControlFileSystem.

  5. Set the variable strValueName to the name of the first entry from which the value is being retrieved (NtfsDisable8dot3NameCreation).

  6. Use the GetDWORDValue method to read the first registry value. This method requires the following parameters:

    • HKEY_LOCAL_MACHINE— Constant required to access HKEY_LOCAL_MACHINE.

    • strKeyPath— Registry path within HKEY_LOCAL_MACHINE.

    • strValueName— Registry entry being read.

    • dwValue— Out parameter that will be set to the registry value. For example, if NtfsDisable8dot3NameCreation is equal to 0, then dwValue is also be equal to 0.

  7. Use an If Then construct to evaluate dwValue and echo the appropriate message. For example, if dwValue is 1, the message “No value set for disabling 8.3 file name creation” is echoed to the screen.

  8. Repeat the process with the remaining registry values.

Example 10.17. Enumerating NTFS Properties

 1 Const HKEY_LOCAL_MACHINE = &H80000002
 2
 3 strComputer = "."
 4 Set objRegistry = GetObject _
 5     ("winmgmts:{impersonationLevel=impersonate}!\" & _
 6          strComputer & "
ootdefault:StdRegProv")
 7
 8 strKeyPath = "SystemCurrentControlSetControlFileSystem"
 9 strValueName = "NtfsDisable8dot3NameCreation"
10 objRegistry.GetDWORDValue _
11     HKEY_LOCAL_MACHINE,strKeyPath,strValueName,dwValue
12
13 If IsNull(dwValue) Then
14     Wscript.Echo "No value set for disabling 8.3 file name creation."
15 ElseIf dwValue = 1 Then
16     WScript.Echo "No 8.3 file names will be created for new files."
17 ElseIf dwValue = 0 Then
18     Wscript.Echo "8.3 file names will be created for new files."
19 End If
20
21 strValueName = "NtfsAllowExtendedCharacterIn8Dot3Name"
22 objRegistry.GetDWORDValue _
23     HKEY_LOCAL_MACHINE,strKeyPath,strValueName,dwValue
24
25 If IsNull(dwValue) Then
26     Wscript.Echo "No value set for allowing extended characters in " _
27        & " 8.3 file names."
28 ElseIf dwValue = 1 Then
29     WScript.Echo "Extended characters are permitted in 8.3 file names."
30 ElseIf dwValue = 0 Then
31     Wscript.Echo "Extended characters not permitted in 8.3 file names."
32 End If
33
34 strValueName = "NtfsMftZoneReservation"
35 objRegistry.GetDWORDValue _
36     HKEY_LOCAL_MACHINE,strKeyPath,strValueName,dwValue
37
38 If IsNull(dwValue) Then
39     Wscript.Echo "No value set for reserving the MFT zone."
40 ElseIf dwValue = 1 Then
41     WScript.Echo _
42         "One-eighth of the disk has been reserved for the MFT zone."
43 ElseIf dwValue = 2 Then
44     Wscript.Echo "One-fourth of the disk reserved for the MFT zone."
45 ElseIf dwValue = 3 Then
46     Wscript.Echo "Three-eighths of the disk reserved for the MFT zone."
47 ElseIf dwValue = 4 Then
48     Wscript.Echo "One half of the disk reserved for the MFT zone."
49 End If
50
51 strValueName = "NtfsDisableLastAccessUpdate"
52 objRegistry.GetDWORDValue _
53     HKEY_LOCAL_MACHINE,strKeyPath,strValueName,dwValue
54
55 If IsNull(dwValue) Then
56     Wscript.Echo "No value set for disabling the last access update " _
57         & "for files and folder."
58 ElseIf dwValue = 1 Then
59     WScript.Echo _
60          "The last access timestamp will not be updated on files " _
61               & "and folders."
62 ElseIf dwValue = 0 Then
63     Wscript.Echo "The last access timestamp updated on files and " _
64          & "folders."
65 End If
66
67 strValueName = "Win31FileSystem"
68 objRegistry.GetDWORDValue _
69     HKEY_LOCAL_MACHINE,strKeyPath,strValueName,dwValue
70
71 If IsNull(dwValue) Then
72     Wscript.Echo "No value set for using long file names and " _
73         & "timestamps."
74 ElseIf dwValue = 1 Then
75     WScript.Echo "Long file names and extended timestamps are used."
76 ElseIf dwValue = 0 Then
77     Wscript.Echo "Long file names and extended timestamps are not used."
78 End If

Modifying NTFS Properties

NTFS is a more sophisticated file system than either FAT or FAT32. Because NTFS tracks additional attributes, such as quota information, reparse points, and file and folder permissions, NTFS typically provides slower access to files and folders on small volumes (less than 1 GB). On larger volumes, however, the superior search algorithms used in NTFS often make NTFS faster than either FAT or FAT32.

However, unlike FAT or FAT32, NTFS allows you to modify the way the file system works. In some cases, this enables NTFS to work faster and more efficiently, thus negating the performance advantage FAT or FAT32 might have on some volumes. The NTFS properties are not exposed directly. However, you can configure the properties by modifying the registry entries shown in Table 10.9.

Table 10.9. Registry Entries for NTFS Properties

Registry Entry/Data Type

Description

NtfsDisable8dot3NameCreation REG_DWORD

Do one of the following:

  • Set the value to 0 to enable the creation of 8.3 file names.

  • Set the value to 1 to disable the creation of 8.3 file names.

You must restart the computer before this change takes effect.

NtfsAllowExtendedCharacterIn8Dot3Name REG_DWORD

Do one of the following:

  • Set the value to 0 to limit 8.3 file names to the ASCII character set.

  • Set the value to 1 to allow the use of extended characters in 8.3 file names.

NtfsMftZoneReservation REG_DWORD

Do one of the following:

  • Set the value to 1 to reserve one-eighth of the volume for the MFT. This is recommended for volumes with relatively few files.

  • Set the value to 2 to reserve one-fourth of the volume for the MFT. This is recommended for a volume with a moderate number of files.

  • Set the value to 3 to reserve three-eighths of the volume for the MFT. This is recommended for a volume with a moderate number of files.

  • Set the value to 4 to reserve one-half of the volume for the MFT. This is recommended for volumes with a large number of files.

NtfsDisableLastAccessUpdate REG_DWORD

Do one of the following:

  • Set the value to 0 to enable updating of the last access timestamp.

  • Set the value to 1 to disable updating of the last value timestamp. This is most effective for folders that contain 100,000 or more files.

Win31FileSystem REG_DWORD

Do one of the following:

  • Set the value to 0 to enable the use of long file names and extended timestamps. MS-DOS and Windows 3.x computers can access the files but cannot update the timestamps.

  • Set the value to 1 to disable the use of long file names and extended timestamps. Only those features of the FAT file system that are available to Windows 3.1 and earlier are used.

You must restart the computer before this change takes effect.

Caution

Caution

Changing the registry with a script can easily propagate errors. The scripting tools bypass safeguards, allowing settings that can damage your system, or even require you to reinstall Windows. Before scripting changes to the registry, test your script thoroughly and back up the registry on every computer on which you will make changes. For more information about scripting changes to the registry, see the Registry Reference on the Windows 2000 Server Resource Kit companion CD or at http://www.microsoft.com/reskit.

Scripting Steps

Listing 10.18 contains a script that modifies the NTFS file system properties on a computer. To carry out this task, the script must perform the following steps:

  1. Create a constant named HKEY_LOCAL_MACHINE and set the value to &H80000002. The Standard Registry Provider requires this value when connecting to the HKEY_LOCAL_MACHINE portion of the registry. (For more information about using the WMI Standard Registry Provider, see the “Registry” chapter in this book.)

  2. Create a variable to specify the computer name.

  3. Use a GetObject call to connect to the WMI namespace rootdefault:StdRegProv on the computer, and set the impersonation level to “impersonate.”

  4. Set the variable strValueName to the path within the HKEY_LOCAL_MACHINE portion of the registry (SystemCurrentControlSetControlFileSystem).

  5. Set the variable strValueName to the name of the entry being modified (Win31FileSystem).

  6. Use the SetDWORDValue method to configure the new registry entry. This method requires the following parameters:

    • HKEY_LOCAL_MACHINE— Constant required to access HKEY_LOCAL_MACHINE

    • strKeyPath— Registry path within HKEY_LOCAL_MACHINE

    • strValueName— Registry entry being modified

    • dwValue— New value for Win31FileSystem

Example 10.18. Modifying File System Properties

 1 const HKEY_LOCAL_MACHINE = &H80000002
 2 strComputer = "."
 3
 4 Set objRegistry = GetObject _
 5     ("winmgmts:{impersonationLevel=impersonate}!\" & _
 6         strComputer & "
ootdefault:StdRegProv")
 7
 8 strKeyPath = "SystemCurrentControlSetControlFileSystem"
 9 strValueName = "Win31FileSystem"
10 dwValue = 1
11 objRegistry.SetDWORDValue _
12     HKEY_LOCAL_MACHINE,strKeyPath,strValueName,dwValue

Managing Page Files

The Windows 2000 operating system supports virtual memory. With virtual memory, a special file on a hard disk (known as a page file or a swap file) is used to supplement the physical memory installed on a computer. When a computer begins to run low on physical memory, data can be “swapped out” to the page file. This has the following advantages:

  • It frees up physical memory.

  • It makes it relatively fast and easy to retrieve the data, because the system knows exactly where to look for it.

Page files and virtual memory are extremely important to fast and effective computing. Without page files, computers would need double or triple the amount of physical memory in order to achieve the same level of performance.

System administrators need to review page file settings as part of a management routine that ensures that page files have been sized optimally and that each drive on a computer has its own page file. In addition, page file usage should be monitored on a regular basis; excessive paging often means that a computer has too little physical memory to carry out the tasks assigned to it.

WMI has several classes that can be used to help manage page files, including the Win32_PageFile class, which returns detailed information about each page file on a computer. Table 10.10 shows several of the key properties of this class.

Table 10.10. Win32_PageFile Properties

Property

Description

CreationDate

File creation date.

CSName

Name of the computer system.

Description

Description of the object.

Drive

Drive letter (including colon) of the file.

EightDotThreeFileName

MS-DOS–compatible file name for this file.

FileSize

Size of the file (in bytes).

InitialSize

Initial size of the page file, in megabytes.

InstallDate

Date the page file was created.

MaximumSize

Maximum size of the page file as set by the user. The operating system does not allow the page file to exceed this limit.

Name

File name of the page file.

Path

Path of the file. This includes leading and trailing backslashes.

Scripting Steps

Listing 10.19 contains a script that enumerates the properties of all the page files on a computer. To carry out this task, the script must perform the following steps:

  1. Create a variable to specify the computer name.

  2. Use a GetObject call to connect to the WMI namespace rootcimv2, and set the impersonation level to “impersonate.”

  3. Use the ExecQuery method to query the Win32_PageFile class.

    This returns a collection of all the page files on the computer.

  4. For each page file in the collection, echo the values of such properties as the file name, current file size, initial file size, and maximum file size.

Example 10.19. Enumerating Page File Properties

 1 strComputer = "."
 2 Set objWMIService = GetObject("winmgmts:" _
 3     & "{impersonationLevel=impersonate}!\" & strComputer & "
ootcimv2")
 4 Set colPageFiles = objWMIService.ExecQuery _
 5     ("SELECT * FROM Win32_PageFile")
 6 For each objPageFile in colPageFiles
 7     Wscript.Echo "Creation Date: " & objPageFile.CreationDate
 8     Wscript.Echo "Description: " & objPageFile.Description
 9     Wscript.Echo "Drive: " & objPageFile.Drive
10     Wscript.Echo "FileName: " & objPageFile.FileName
11     Wscript.Echo "FileSize: " & objPageFile.FileSize
12     Wscript.Echo "InitialSize: " & objPageFile.InitialSize
13     Wscript.Echo "InstallDate: " & objPageFile.InstallDate
14     Wscript.Echo "MaximumSize: " & objPageFile.MaximumSize
15     Wscript.Echo "Name: " & objPageFile.Name
16     Wscript.Echo "Path: " & objPageFile.Path
17 Next

Monitoring Page File Use

The Win32_PageFileUsage class enables you to obtain basic information about each page file on a computer, including the allocated file size, the current file size, and the largest size the file has reached since the computer started. This class is useful for routine monitoring of each page file.

As long as the maximum size of the file is less than 70 percent of the allocated size, it is generally safe to assume the page file is correctly configured.

Table 10.11 shows some of the key properties of the Win32_PageFileUsage class.

Table 10.11. Win32_PageFileUsage Properties

Property

Description

AllocatedBaseSize

Actual amount of disk space allocated for use with this page file. This value corresponds to the range established in Win32_PageFileSetting under the InitialSize and MaximumSize properties, set at system startup.

CurrentUsage

Amount of disk space currently used by the page file.

Description

Description of the object.

InstallDate

Date the page file was created.

Name

Path and file name of the page file.

PeakUsage

Highest use page file.

Scripting Steps

Listing 10.20 contains a script that monitors page file use on a computer. To carry out this task, the script must perform the following steps:

  1. Create a variable to specify the computer name.

  2. Use a GetObject call to connect to the WMI namespace rootcimv2, and set the impersonation level to “impersonate.”

  3. Use the ExecQuery method to query the Win32_PageFileUsage class.

    This returns a collection of statistics for each of the page files on the computer.

  4. For each page file in the collection, echo the value of properties such as the current usage, the peak usage, and the file status.

Example 10.20. Monitoring Page File Use

 1 strComputer = "."
 2 Set objWMIService = GetObject("winmgmts:" _
 3     & "{impersonationLevel=impersonate}!\" & strComputer & "
ootcimv2")
 4 Set colPageFiles = objWMIService.ExecQuery _
 5     ("SELECT * FROM Win32_PageFileUsage")
 6 For each objPageFile in colPageFiles
 7     Wscript.Echo "Allocated Base Size: " & objPageFile.AllocatedBaseSize
 8     Wscript.Echo "CurrentUsage: " & objPageFile.CurrentUsage
 9     Wscript.Echo "Description: " & objPageFile.Description
10     Wscript.Echo "InstallDate: " & objPageFile.InstallDate
11     Wscript.Echo "Name: " & objPageFile.Name
12     Wscript.Echo "PeakUsage: " & objPageFile.PeakUsage
13 Next

Configuring Page File Properties

When you install Windows on a computer, the operating system automatically sets up and configures a page file for you. In many cases, those settings will be adequate, and you will never need to reconfigure the page file.

In other cases, however, the settings might prove less than optimal. If a page file is too small, applications might run short on virtual memory. If a page file is too large, you might be wasting disk space that could be used for other purposes. In either case, you can reconfigure the page file settings in order to promote faster and more efficient computing.

You can use the Win32_PageFileSetting class to modify both the initial size and the maximum size of any page file on your computer. Table 10.12 describes the properties of the Win32_PageFileSetting class.

Table 10.12. Win32_PageFileSetting Properties

Property

Description

InitialSize

Initial size of the page file, in megabytes.

MaximumSize

Maximum size of the page file, in megabytes.

Name

Path and file name of the page file.

Note

Note

You must restart the computer before the new page file settings take effect.

Scripting Steps

Listing 10.21 contains a script that configures the page file properties on a computer. To carry out this task, the script must perform the following steps:

  1. Create a variable to specify the computer name.

  2. Use a GetObject call to connect to the WMI namespace rootcimv2, and set the impersonation level to “impersonate.”

  3. Use the ExecQuery method to query the Win32_PageFileSetting class.

    This returns a collection of all the page files on the computer.

  4. For each page file in the collection, set the InitialSize to 300 MB and the MaximumSize to 600 MB.

  5. Use the Put_ method to apply the changes and modify the page file settings.

Example 10.21. Configuring Page File Properties

 1 strComputer = "."
 2 Set objWMIService = GetObject("winmgmts:" _
 3     & "{impersonationLevel=impersonate}!\" & strComputer & "
ootcimv2")
 4 Set colPageFiles = objWMIService.ExecQuery _
 5     ("SELECT * FROM Win32_PageFileSetting")
 6 For Each objPageFile in colPageFiles
 7     objPageFile.InitialSize = 300
 8     objPageFile.MaximumSize = 600
 9     objPageFile.Put_
10 Next
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset