Friday, March 18, 2011
The 2003 powershell goes on :-)
Again, there are no available modules so i had to create my own.
How to set disk quota for a certain user (in megabytes) on a certain Windows 2003 server on a certain drive? Here’s how:
function set_disk_quota($username, $quota_hard, $computername, $disk)
{
# preferred quota mode is enabled+deny access to disk, which is type 2
# for logging purposes only but still allow disk access, select type 1
$default_quota_mode = "2"
$query_quota_enabled_or_not = "select * from Win32_QuotaSetting where VolumePath='"+$disk+":\\'"
$query_user = "select * from Win32_Account where name='"+$username+"'"
$query_disk = "select * from Win32_LogicalDisk where DeviceID='"+$disk+":'"
$quota_disk = get-wmiobject -query $query_quota_enabled_or_not -computername $computername
if ($quota_disk.State -eq "0")
{
echo "CHECK - ERROR - state 0 = Quota not enabled on disk -$disk- of -$computername-"
echo "setting quota"
$quota_disk.State = $default_quota_mode
$quota_disk.Put()
}
if ($quota_disk.State -eq "1")
{
echo "CHECK - WARNING - state 1 = Quota enabled on disk -$disk- of -$computername- but not access is not denied when over quota"
echo "setting quota"
$quota_disk.State = $default_quota_mode
$quota_disk.Put()
}
if ($quota_disk.State -eq "2")
{
echo "CHECK - OK - state 2 = Quota enabled on disk -$disk- of -$computername- and access is denied when over quota"
}
$objAccount = get-wmiobject -query $query_user
$objDisk = get-wmiobject -query $query_disk
$objquota = (new-object management.managementclass Win32_DiskQuota).CreateInstance()
$objquota.User = $objAccount.Path.RelativePath
$objquota.QuotaVolume = $objDisk.Path.RelativePath
if ($quota_hard -eq "0")
{
$objquota.Delete()
echo "Quota deleted for $username"
}
else
{
$objquota.Limit = [int]$quota_hard * 1024 * 1024 * 1
# Set the warning level to 90% of the $hard_limit
$objquota.WarningLimit = [int]$quota_hard * 1024 * 1024 * 0.9
$objquota.put()
}
}
Wednesday, March 16, 2011
To translate the timestamps in your dmesg into human readable timestamps, use the following perl script:
#!/usr/bin/perl
$uptime = `cat /proc/uptime | awk '{print $1}';`;
$boot = time() - $uptime;
chomp $boot;
while (<STDIN>) {
if ($_ =~ /^\[([\s\d\.]+)\]/) {
$time_offset = $1;
}
$real_time = sprintf scalar localtime($boot + $time_offset);
$_ =~ s/\[[\s\d\.]+\]/\[$real_time\]/;
print $_;
}
e.g.
[ 9.815650] 3w-9xxx: scsi2: ERROR: (0x03:0x0101): Invalid command opcode:opcode=0x85.
will be translated into
[Wed Mar 16 16:02:32 2011] 3w-9xxx: scsi2: ERROR: (0x03:0x0101): Invalid command opcode:opcode=0x85.
Syntax:
dmesg | perl /root/print_time_offset.pl
Thursday, March 3, 2011
Because i need to maintain lots of Exchange 2003 servers and there are no Exchange 2003 powershell modules, i’m writing my own.
Here’s a piece of code that handles the forwarding of mail for users.
As you know, forwarding mail for a mailbox/user involves creating a contact with an external smtp address in Active Directory. Next, that contact can be assigned to the mailbox and a forwarding mode can be selected.
This script will handle all of those functions for you.
The script uses two global variables (customize to match your own Active Directory and/or place where you want to create these forwarding contacts):
$FQDN=",DC=netherlands,DC=europe,DC=microsoft,DC=com"
$base_security_groups_container="CN=Users"
Here’s the code:
function set_forward_mail($username, $forwarding_mode, $forwarding_address)
{
# forwarding_mode
# 0 = forwarding disabled
# 1 = forward without local delivery
# 2 = forward with local delivery
if ($forwarding_mode -eq "2")
{
if (!(get-qadobject -identity "$username (forwarded by PowershellApp)"))
{
# contact doesn't exist (yet). Create now
New-QADObject -ParentContainer "$base_security_groups_container$FQDN" -type "contact" -name "$username (forwarded by PowershellApp)" -DisplayName "$username (forwarded by PowershellApp)" -ObjectAttributes @{Description="$username (forwarded by PowershellApp)";mail="$forward_address";targetAddress="SMTP:$forwarding_address";mailNickname="$username"+"_forwarded_by_PowershellApp";msExchHideFromAddressLists=$true}
# Recipient Update Service will do the rest.
# Set the forwarding mode, type 2
$forward_user_dn = (Get-QADObject -identity "$username (forwarded by PowershellApp)" | Select-Object dn).dn
set-qaduser -identity $username -objectAttributes @{deliverAndRedirect=$true;altRecipient=$forward_user_dn}
}
else
{
# contact DOES exist. Update
set-qadobject -identity "$username (forwarded by PowershellApp)" -ObjectAttributes @{Description="$username (forwarded by PowershellApp)";mail="$forward_address";targetAddress="SMTP:$forwarding_address";mailNickname="$username"+"_forwarded_by_PowershellApp";msExchHideFromAddressLists=$true}
# clear any old addresses in the list of addresses and make the new one primary
get-qadobject -identity "$username (forwarded by PowershellApp)" | Clear-QADProxyAddress | Add-QADProxyAddress -Address "SMTP:$forwarding_address" -Primary
# make sure the forwarding mode is correct, type 2
$forward_user_dn = (Get-QADObject -identity "$username (forwarded by PowershellApp)" | Select-Object dn).dn
set-qaduser -identity $username -objectAttributes @{deliverAndRedirect=$true;altRecipient=$forward_user_dn}
}
}
if ($forwarding_mode -eq "1")
{
if (!(get-qadobject -identity "$username (forwarded by PowershellApp)"))
{
# contact doesn't exist (yet). Create now
New-QADObject -ParentContainer "$base_security_groups_container$FQDN" -type "contact" -name "$username (forwarded by PowershellApp)" -DisplayName "$username (forwarded by PowershellApp)" -ObjectAttributes @{Description="$username (forwarded by PowershellApp)";mail="$forward_address";targetAddress="SMTP:$forwarding_address";mailNickname="$username"+"_forwarded_by_PowershellApp";msExchHideFromAddressLists=$true}
# Recipient Update Service will do the rest.
# Set the forwarding mode, type 2
$forward_user_dn = (Get-QADObject -identity "$username (forwarded by PowershellApp)" | Select-Object dn).dn
set-qaduser -identity $username -objectAttributes @{deliverAndRedirect=$false;altRecipient=$forward_user_dn}
}
else
{
# contact DOES exist. Update
set-qadobject -identity "$username (forwarded by PowershellApp)" -ObjectAttributes @{Description="$username (forwarded by PowershellApp)";mail="$forward_address";targetAddress="SMTP:$forwarding_address";mailNickname="$username"+"_forwarded_by_PowershellApp";msExchHideFromAddressLists=$true}
# clear any old addresses in the list of addresses and make the new one primary
get-qadobject -identity "$username (forwarded by PowershellApp)" | Clear-QADProxyAddress | Add-QADProxyAddress -Address "SMTP:$forwarding_address" -Primary
# make sure the forwarding mode is correct, type 2
$forward_user_dn = (Get-QADObject -identity "$username (forwarded by PowershellApp)" | Select-Object dn).dn
set-qaduser -identity $username -objectAttributes @{deliverAndRedirect=$false;altRecipient=$forward_user_dn}
}
}
if ($forwarding_mode -eq "0")
{
if (!(get-qadobject -identity "$username (forwarded by PowershellApp)"))
{
# contact doesn't exist, just disable forwarding
set-qaduser -identity $username -objectAttributes @{deliverAndRedirect=$false;altRecipient=""}
}
else
{
# contact DOES exist. disable forwarding and delete contact
set-qaduser -identity $username -objectAttributes @{deliverAndRedirect=$false;altRecipient=""}
Remove-QADObject -identity "$username (forwarded by PowershellApp)" -Force
}
}
}
Wednesday, March 2, 2011
Because of some issue between Windows XP and a HP 6000 Pro system, i needed to rollout a script to ~10000 clients that detected the type of system and change the boot.ini accordingly.
Microsoft’s article on this “bug”.
' Quick'n Dirty HP 6000 Pro boot.ini (/usepmtimer) changer (c) Hugo
On Error Resume Next
Set objFSO = CreateObject("Scripting.FilesystemObject")
Set objShell = CreateObject("WScript.Shell")
Set objNetwork = CreateObject("WScript.Network")
Set WSHProcessEnvironment = objShell.Environment("Process")
strComputerName = "."
strWinMgt = "winmgmts://" & strComputerName &""
Set ComputerSystemSet = GetObject(strWinMgt).ExecQuery("select * from Win32_ComputerSystem")
For Each objComputerSystem In ComputerSystemSet
strComputerSystem_Model = objComputerSystem.Model
strComputerSystem_Description = objComputerSystem.Description
Next
WScript.Echo " Found: " + strComputerSystem_Model
' Learned so far:
' - "HP Compaq 6000 Pro MT PC"
' - "HP Compaq 6000 Pro SFF PC"
' - "HP Compaq 6000 Small Form Factor"
' - ..
Select Case strComputerSystem_Model
Case "HP Compaq 6000 Pro MT PC"
boot_ini_aanpassen()
Case "HP Compaq 6000 Pro SFF PC"
boot_ini_aanpassen()
Case "HP Compaq 6000 Small Form Factor"
boot_ini_aanpassen()
Case "blablabla pro 6000 type 4 that will be found some day or the next"
boot_ini_aanpassen()
Case Else
WScript.Echo " No Pro 6000 detected, exit ..."
End Select
'#########################################################################
' support function(s)
'#########################################################################
Function boot_ini_aanpassen()
WScript.Echo " Match found, now change boot.ini"
' make the file accessable
objShell.Run "c:\windows\system32\attrib.exe -h -a -r -s c:\boot.ini"
' sleep for a while because it needs time to process the attribute change (10 sec will do for sure)
WScript.Sleep(10000)
' define new boot.ini layout
strMyBootIni_line1 = "[boot loader]"
strMyBootIni_line2 = "timeout=30"
strMyBootIni_line3 = "default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS"
strMyBootIni_line4 = "[operating systems]"
strMyBootIni_line5 = "multi(0)disk(0)rdisk(0)partition(1)\WINDOWS=""Microsoft Windows XP Professional"" /fastdetect /usepmtimer"
Const WriteMode = 2 '2 = ForWrite, 8 = ForAppend
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile ("c:\boot.ini", WriteMode, True)
objTextFile.WriteLine(strMyBootIni_line1)
objTextFile.WriteLine(strMyBootIni_line2)
objTextFile.WriteLine(strMyBootIni_line3)
objTextFile.WriteLine(strMyBootIni_line4)
objTextFile.WriteLine(strMyBootIni_line5)
objTextFile.Close
' re-attribute the file
objShell.Run "c:\windows\system32\attrib.exe +h +a +r +s c:\boot.ini"
WScript.Echo " Boot.ini changed. Active after next reboot"
End Function