Friday, March 18, 2011
powershell - set disk quota using wmi
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
dmesg timestamps
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
exchange 2003 powershell - forwarding
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
VBS detect type of computer (using WMI)
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
Tuesday, March 1, 2011
Quick Sound Switch
One of those fine freeware utilities i have to remember: http://www.quicksoundswitch.toflo.de/eng/index.html
This comes in handy if you have multiple audio cards (e.g. normal audio card and audio over HDMI) and you want to quickly switch between primary output device.
Local mirror of version 2.11 in case the original site ever goes down: QuickSoundSwitch version 2.11