Wednesday, December 22, 2010

exchange 2003 powershell - create mailbox

As i told before, it’s not that easy to make changes with powershell to your Exchange 2003 environment as it is nowadays with Exchange 2010.
Since it was pretty hard to read certain values from Active Directory, i’m doing a pretty nasty trick: copy the values from an existing user.

Here’s how to create a mailbox for an existing user:

function add_exchange2003_mailbox_for_user($username)
{
  # to keep it simple: let's copy the properties of a template user, e.g. Administrator, and create the mailboxes in the same database
  $template_user = "Administrator"
  $userproperties = get-qaduser -identity $template_user -IncludeAllProperties
  set-qaduser -identity $username -objectAttributes @{msExchHomeServerName=$userproperties.MsExchHomeServerName}
  set-qaduser -identity $username -objectAttributes @{mailnickname="$username"}
  set-qaduser -identity $username -objectAttributes @{mDBUseDefaults='TRUE'}
  set-qaduser -identity $username -objectAttributes @{homeMBD=$userproperties.homeMDB}
  # now the Recipient Update Service will do the rest ...
}

exchange 2003 powershell - add primary address

When you’re making changes to your active directory or exchange environment with powershell, it’s a piece of cake with Windows 2008 R2 and/or Exchange 2010. All the cmdlets are there by default.
But when you’re dealing with Windows 2003 and/or Exchange 2003, it’s a whole different story.
I will be posting some of my scripts for Windows 2003 and Exchange 2003 from now on.
Because Windows 2003 has no active directory powershell module, i’m using the Quest AD Templates for that purpose (highly recommended!).

Here’s how to change the primary address for an exchange 2003 user:

function set_exchange2003_primary_address($username, $primary_smtp_address)
{
  # lowercase the to-be-added address
  $primary_smtp_address = $primary_smtp_address.ToLower()
  
  # get current addresses
  $userinfo = get-qaduser -identity $username
  $new_proxyaddresses = $userinfo.ProxyAddresses

  # lowercase all the "SMTP:" entries
  foreach ($number in 0..($new_proxyaddresses.Count - 1) )
  {
    $address = $new_proxyaddresses[$number]
    $new_proxyaddresses[$number]=$address.Replace("SMTP:", "smtp:")
  }
  
  # Next, check if the to-be-added address is allready in the list
  $allready_in_list = $FALSE
  foreach ($number in 0..($new_proxyaddresses.Count - 1) )
  {
    $address = $new_proxyaddresses[$number].ToLower()
    $check = $address.CompareTo("smtp:$primary_smtp_address")
    if ($check -eq 0)
    {
      # address is found in the list. Make it PRIMARY
      $new_proxyaddresses[$number]=$address.Replace("smtp:", "SMTP:")
      $allready_in_list = $TRUE
    }
  }  
  # But if it's not found, add the new adress to the list as primary
  if ($allready_in_list -eq $FALSE)
  {
    $new_proxyaddresses += 'SMTP:'+$primary_smtp_address
  }

  # now write the addresses to active directory
  set-qaduser -identity $username -objectAttributes @{ProxyAddresses=$new_proxyaddresses}
}

Hmm..
Guess I should have payed more attention… Why not do this:

function set_exchange2003_primary_address($username, $primary_smtp_address)
{
  get-qaduser -identity $username | Add-QADProxyAddress -Address $primary_smtp_address -Primary
}

Monday, December 20, 2010

Bootvis

If you know what it is and (also) looking for it: Bootvis

Friday, November 12, 2010

areca use extra space after swapping hd’s

Say you have a raid5 volume of 3×500GB disks with an effective space of ~1TB.
You plug out 1 disk, swap it with a 1TB disk and let the areca rebuild the array.
You do the same for disk 2 and 3.
You’d probably think you’ll have an extra TB to use. But the areca won’t show you. Here’s how (undocumented feature):

  1. Login the browser management console (Raidset Functions > Rescue RaidSet)
  2. Enter the keyword “RESETCAPACITY Raid Set # 000”, confirm and submit. After that, controller will reconfigure the raidset capacity.
  3. Create an extra logical drive on the raidset

Thursday, November 11, 2010

renew a self-signed ssl certificate on exchange 2007

To renew a self-signed ssl certificate on an Exchange 2007 server:

Start the Exchange Management Shell, then:

Get-ExchangeCertificate -DomainName CAS01.contoso.com

Find the certificate that contains a “W” from the list of certificates For example, select IP.WS. The “W” indicates that the certificate is assigned to IIS.
Then to clone the certificate, run the following cmdlet (the thumbprint is unique):

Get-ExchangeCertificate -Thumbprint c4248cd7065c87cb942d60f7293feb7d533a4afc | New-ExchangeCertificate

The new cloned certificate will then be stamped with a new expiration date one year after the date you run the cmdlet.

And last but not least: assign the certificate to a service:

Enable-ExchangeCertificate -Thumbprint c4248cd7065c87cb942d60f7293feb7d533a4afc -Service IIS

Tuesday, November 9, 2010

rescan scsi bus without rebooting

If you attach an extra harddisk to your virtual machine and you don’t want to reboot, all you need to do is rescan your scsi bus.

First determine how many scsi adapters your system has:

# ls /sys/class/scsi_host
host0

Then order the rescan command to the adapter:

# echo "- - -" > /sys/class/scsi_host/host0/scan

Check your dmesg or /proc/partitions!

Monday, November 8, 2010

find LVM volumes

I needed to make a backup of an old server. So i booted an Ubuntu live cd. Then:

cat /proc/partitions

But I wasn’t able to mount certain partitions. It appeared to be lvm volumes.
To mount them, you’ll need the lvm2 package first.

sudo -s
apt-get update
apt-get install lvm2

Then find the volumes.

vgchange -a y
  3 logical volume(s) in volume group "VolGroup00" now active

Now look in your device mapper:

ls /dev/mapper/

.. and do whatever you like with it. In my case:

mkdir /mnt/vol00
mkdir /mnt/vol01
mkdir /mnt/vol02
mount /dev/mapper/VolGroup00-LogVol00 /mnt/vol00
mount /dev/mapper/VolGroup00-LogVol01 /mnt/vol01
  /dev/mapper/VolGroup00-LogVol01 looks like swapspace - not mounted
root@ubuntu:~# mount /dev/mapper/VolGroup00-LogVol02 /mnt/vol02

apt-get install smbfs
mkdir /mnt/targetserver/
smbmount //10.2.18.224/software /mnt/targetserver/
mkdir /mnt/targetserver/serverbackup/

cd /mnt
rsync -av vol00 vol02 /mnt/targetserver/

Tuesday, November 2, 2010

Log all output to a file (dos, bash)

I’m always googling for this. What was that thing again that logs all output to a file?

2>&1

Bash example:

root@ubuntu:/mnt/sda6# rsync -av * /mnt/backup/sda6/ >/mnt/backup/readrrors.txt 2>&1

Dos example:

copy backup.log \\nas\share\weeklog.txt >output.txt 2>&1

Monday, November 1, 2010

Export .pst files in Exchange 2010 SP1

In addition to the import procedures, here’s how to export to .pst files:

Add an import to the queue:

New-MailboxExportRequest -Mailbox p.puk -FilePath "\\FS01\data\Backup Mailbox (PST)\p.puk.pst"

And status:

Get-MailboxExportRequest

Paste as plain text

Have you ever copied some text from a web page or a document and then wanted to paste it as simple text into another application without getting all the formatting from the original source? PureText makes this simple by adding a new Windows hot-key (default is WINDOWS+V) that allows you to paste text to any application without formatting.

Download this 13KB utility here!

Friday, October 29, 2010

Import .pst files in Exchange 2010 SP1

SP1 for Exchange 2010 has a new approach for importing .pst files.
First of all make sure the group “Exchange Trusted Subsystem” has NTFS permissions on the folder which contains all the .pst files.
Second, make sure this folder has been shared. Exchange only accepts unc paths.
Third, you have to make a new role assignment to a security group.
Create a universal group called “Mailbox Import Export Access” in active directory and add the user who’s going to do the export. Next, from the Exchange Management Shell:

New-ManagementRoleAssignment -Name "Mailbox Import Export Access" -SecurityGroup "Mailbox Import Export Access" -Role "Mailbox Import Export"

All the preparations have been made.

To queue (yes queue!) the import for a user:

New-MailboxImportRequest -Mailbox p.puk -FilePath "\\FS01\data\Backup Mailbox (PST)\p.puk.pst"

You can repeat the line for other users or pipe a list of users to build a bigger queue.

The following command shows the queue and the status of all imports:

Get-MailboxImportRequest

or

get-mailboximportrequest | fl filepath,status

One drawback so far:
I haven’t been able to find a way to set the locale by default (was possible with non-SP1 by typing

-locale "nl-NL"

for Dutch users) which is really annoying since users will end up with “Inbox” instead of “Postvak In”, “Sent Items” instead of “Verzonden Items”, etc.
This can be overcome by logging in to the webmail before starting the import and set the default language from there (first question asked when logging in). But that’s still annoying.

Update 2011/03/25
I haven’t been able to test it yet but running the following command prior to the import might do the trick ….

Set-MailboxRegionalConfiguration p.puk -Language "nl-NL" -DateFormat "dd-MM-yyyy" -LocalizeDefaultFolderName:$true

or for all mailboxes

get-mailbox | set-mailboxregionalconfiguration -Language nl-NL -DateFormat "dd-MM-yyyy" -LocalizeDefaultFolderName:$true

Wednesday, October 27, 2010

Change domain admin password (without AD restore mode)

Today i needed access to a domain of servers, but one of our competitors would not provide us with the Administrator password, so i needed other ways to get in.

Petri.co.il has a nice page on that subject that consists of 2 steps:

  1. change the local administrator password (so you can boot into Active Directory restore mode)
  2. install a service to change the domain password

Somehow step 1 lead me to corrupt SAM/Software/system files so after restoring the original files i figured a way to skip that.

All you need is a Windows live cd or usb stick and the zipfile below. BartPE will do. Or use a commercial product like Active@ Boot Disk, which is really nice because of the fact that it’s based on a Vista kernel which supports the loading of drivers without rebooting. So you’re able to load drivers for raidcontrollers or other devices and your drives will appear directly.
Download this file and put it on a usb stick.

Now here we go:

  1. Boot your Windows live environment.

  2. Extract the content of the zip-file to c:\.
    You’ll have 2 directories.
    C:\RegEditPE
    C:\srvany

  3. VERY IMPORTANT: make a copy of your c:\windows\system32\config now. Just copy the entire directory to some location.

  4. Start C:\RegEditPE\RegEditPE.exe and after it’s done browse to HKEY_LOCAL_MACHINE.
    You’ll see new hives for windows installations that have been found, e.g. “SYSTEM_ON_G”.

  5. Edit C:\srvany\_service.reg and replace (ctrl+h) “SYSTEM_ON_E” with the one on your system.

  6. Check the line that says:

    "AppParameters"="/k net user Administrator 123456abc /domain"
    

    As you can see the password will be changed to “123456abc” but keep in mind that your domain can have complexity policies! Change to something more complex if needed!

  7. Save the file.

  8. Now doubleclick the file to merge it into the registry and close RegEditPE.

  9. I’ve provided cmd.exe from Windows 2003 SP2 in the zipfile, but you might want to do:

    copy x:\windows\system32\cmd.exe x:\srvany\
    

    (where x is your drive with your Windows installation.

  10. Reboot and wait a little. Now you can log in with your new password.

Tested on Windows 2003 SP2

Thursday, October 14, 2010

Forcing a refresh of Network Printer Settings from Print Server

If you have a printserver in your network and you want to change certain properties, e.g. print black/white instead of color, normally what you do is change the settings on the Advanced Tab - Default Settings Button. These are the settings a user inherits when first connecting to the shared printer.
But what if you want to revert these settings. You’d have to remove the printer from the userprofile and make sure the printer’s readded, in order to inherit the new default settings.

This is exactly what the following script does.
It also cleans removed/unshared printers, as it can only re-add printers that still exist.

on error resume next
Set WshNetwork = WScript.CreateObject("WScript.Network")

'## Enumerate all the current printers in the profile
Set oPrinters = WshNetwork.EnumPrinterConnections

For i = 0 to oPrinters.Count - 1 Step 2

'## Disconnect the printer
WshNetwork.RemovePrinterConnection ""& oPrinters.Item(i+1) &"", true, true
'## Readd the same printer (if still exists)
WshNetwork.AddWindowsPrinterConnection ""& oPrinters.Item(i+1) &"", true, true

Next

msgbox "Done"

You might want to comment the last line to make the script run totally silent.

Monday, September 6, 2010

copy file and directory permissions

If you’re migrating data from one domain to another, sometimes you need to retain file and directory permissions.
Let’s assume you’ve recreated users and security groups the way they were. Then you can do the following:

dump all rights to a file (on the old fileserver)

subinacl /noverbose /outputlog=D:\apps_perms.txt /subdirectories d:\apps\*.* /display

replay the file (on the new fileserver)

subinacl /playfile D:\apps_perms.txt

Wednesday, September 1, 2010

powershell - import .pst files in exchange 2010 (pt2)

In addition to the previous article, you might want to add your default locale to the import-mailbox command.
e.g.

import-mailbox -identity "hugo" -pstfolderpath "c:\pstfiles" -locale "nl-NL"

Otherwise annoying duplicate folders like Inbox/Postvak IN, Calendar/Agenda, Drafts/Concepten, etc will appear.

Wednesday, August 25, 2010

powershell - import .pst files in exchange 2010

I haven’t figured out how to get proper resultcodes or errorhandling from the “Import-Mailbox” command, but you can use your transcript file for that. See my other post for that.

You’ll need some global vars, e.g.:

$your_import_file="c:\import\import.csv"
$folder_with_psts="C:\exmerge\primary database export files"

Then it’s as simple as this:

function import_mailboxes()
{
  $UserDetails=Import-Csv -delimiter ";" $your_import_file
  $count=0
  $found=0
  $notfound=0
  foreach($UD in $UserDetails)
  {
    $count++
    $username=$UD.Code.ToLower()
    $full_path_to_pst=$folder_with_psts + $username + ".pst"
    $FileExists = Test-Path $full_path_to_pst
    if ($FileExists)
    {
      write-host "$count - $username - Ready to import ($full_path_to_pst)" -ForegroundColor Green
      $found++
      Import-Mailbox -Identity $username -PSTFolderPath $folder_with_psts
    }
    else
    {
      write-host "$count - $username - No matching pst file found!" -ForegroundColor Red
      $notfound++
    }
  }
  write-host "Summary: Found (and hopefully successfully imported): $found, Not Found: $notfound"
}

Friday, August 13, 2010

Create lists of all smtp email addresses

Create .csv files from all smtp email addresses in your (exchange 2003) environment.

csvde -f groups.csv -d "dc=home,dc=yourdomain,dc=local" -r "(&(objectClass=group)(mail=*))" -l "DN,displayName,proxyAddresses"
csvde -f users.csv -d "dc=home,dc=yourdomain,dc=local" -r "(&(objectClass=user)(mail=*))" -l "DN,samAccountName,displayName,mail,proxyAddresses"
csvde -f contacts.csv -d "dc=home,dc=yourdomain,dc=local" -r "(&(objectClass=contact)(mail=*))" -l "DN,displayName,targetAddress"

Wednesday, August 11, 2010

Outlook 2007 - Annoyances (RSS, Online Help, Search)

When running Outlook 2007 for the first time, you get those annoying 3 questions.
Download the “2007 Office system (SP2) Administrative Template files (ADM, ADMX, ADML)” (currently for SP2) and add it to your policies. Then:

User Configuration\Administrative Templates\Microsoft Office 2007 system\Privacy\Trust Center\
- enable the "Disable Opt-in Wizard on first run".

User Configuration\Administrative Templates\Microsoft Office Outlook 2007\Tools | Options\Preferences\Search Options\
- enable the "Prevent installation prompts when Windows Desktop Search ..."

User Configuration\Administrative Templates\Microsoft Office Outlook 2007\Tools |Account Settings\RSS Feeds
- disable the "Default RSS Feeds"
- disable the "Synchronize Outlook RSS Feeds with Common Feed List"

Tuesday, August 10, 2010

powershell - mail-enable a user (exchange 2010)

This script uses the RemoteExchange calls for Exchange 2010:

. 'C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1'
Connect-ExchangeServer -auto

And the function:

function enable_mailbox_for_existing_user([string]$username)
{
  $check = get-aduser -Filter { samAccountName -eq $username }
  if($check -eq $null)
  {
    write-host "- User does not exist - ERROR" -ForegroundColor Red
  }
  else
  {
    # seems like the user exists
    $mailbox_test = get-user $username | select recipienttype
    if ($mailbox_test.RecipientType -eq "userMailbox")
    {
      write-host "- User is allready mail-enabled - WARNING" -ForeGroundColor Yellow
    }
    if ($mailbox_test.RecipientType -eq "User")
    {
      Enable-Mailbox -Identity $username -Alias $username | Out-Null
      write-host "- Mailbox for user created - OK" -ForeGroundColor Green
    }
  }
}

powershell - add (a user to) a securitygroup

Again, you’ll need the Windows 2008 r2 ActiveDirectory module for this to work:

import-module ActiveDirectory

Some static variables:

$default_securitygroup_ou="OU=MySecurityGroups,"

And the functions:

function add_security_group([string]$StrGroupName)
{
  $check = get-adgroup -Filter { name -eq $StrGroupName }
  if($check -eq $null)
  {
    $ad_path = $default_securitygroup_ou + (get-addomain).distinguishedname
    New-ADGroup -Path $ad_path -name $StrGroupName -GroupScope Global -GroupCategory Security
    write-host "- Security Group created - OK" -ForeGroundColor Green
  }
  else
  {
    write-host "- Security Group allready exists" -ForeGroundColor Yellow
  }
}

function add_user_to_group([string]$username, [string]$security_group)
{
  $grp = get-adgroup -Filter { name -eq $security_group }
  if ($grp -eq $null)
  {
    write-host "- Security Group does not exist - ERROR" -ForeGroundColor Red
  }
  else
  {
    # group does exist, lets see if the users is allready a member
    $members = get-adgroupmember -Identity $security_group
    foreach ($mem in $members)
    {
      if($mem.samAccountName -eq $username)
      {
        $found = $true
      }
    }
    if ($found)
    {
      write-host "- User is allready a member of this Security Group - WARNING" -ForegroundColor Yellow
    }
    else
    {
      add-adgroupmember -identity $security_group $username
      write-host "- User succesfully added to Security Group - OK" -ForegroundColor Green
    }
  }
}

powershell - add user

In addition to the previous example it would be nice to create users from the .csv files.

You’ll need the Windows 2008 r2 ActiveDirectory module for this to work:

import-module ActiveDirectory

Also i have a couple of static variables:

$default_users_ou="OU=myusers,"
$ad_domain="my.domain.local"
$share_profiles="\\fileserver01\profiles"
$share_users="\\fileserver01\users"
$homeshare_drive="Z:"

And here we go:

function add_user([string]$username, [string]$plaintextpassword, [string]$group, [string]$givenname, [string]$surname, [string]$displayname, [bool]$enabled)
{
  # syntax: add_user f.deboer mypass$78 teacher "Boer, De" "Frank" "Boer, De, Frank" $true

  $check = get-aduser -Filter { samAccountName -eq $username }
  if($check -eq $null)
  {
    $user_password=ConvertTo-SecureString -string $plaintextpassword -asPlainText -Force
    $ad_user_path=$default_users_ou + (get-addomain).distinguishedname
    $loginscript=$group + ".bat"
    New-ADUser -Name $displayname -SamAccountName $username -UserPrincipal "$username@$ad_domain" -AccountPassword $user_password -CannotChangePassword $true -PasswordNeverExpires $true -Enabled $enabled -ProfilePath "$share_profiles\$username" -HomeDirectory $share_users\$username -HomeDrive $homeshare_drive -ScriptPath $loginscript -GivenName $givenname -Surname $surname -DisplayName $displayname -Path $ad_user_path
    write-host "- User Created - OK" -ForeGroundColor Green
  }
  else
  {
    write-host "- User allready exists" -ForeGroundColor Yellow    
  }
}

powershell - parse .csv file

Powershell is ideal for bulk operations, e.g. creating lots of users in active directory.

Say we have a .csv file that looks like this:

loginname;firstname;middlename;lastname;fullname;function;password
f.deboer;f;de;boer;Boer, de, Frank;teacher;mypass$78
r.deboer;r;de;boer;Boer, de, Ronald;teacher;123pass60
m.manager;m;;manager;Manager, Mike;manager;superpassw0rd

You might want to specify some global variables first.

$import_file="d:\import\importfile.csv"

Now let’s create a simple function to read the file.

function readcsvfile()
{
  $UserDetails=Import-Csv -delimiter ";" $import_file
  foreach($UD in $UserDetails)
  {
    $loginname=$UD.loginname
    $firstname=$UD.firstname
    $middlename=$UD.middlename
    $lastname=$UD.lastname
    $fullname=$UD.fullname
    $function=$UD.function
    $password=$UD.password

    echo "$username"
    echo "$password"
    # or something else you want to do with tis information
  }
}

powershell - windows 2008 r2’s ActiveDirectory module

# Modules
# - http://technet.microsoft.com/en-us/library/ee617195.aspx
import-module ActiveDirectory

powershell - log entire session

To log your entire powershell session to a file you can use the start-transcript and stop-transcript commands.

$mypowershellapplicationdir = "c:\myapp"
$logfiledate = (get-date).tostring("yyyyMMddHHssmm") + ".txt"
start-transcript -path $mypowershellapplicationdir\logs\$logfiledate

Stop-transcript will automatically be done when leaving powershell.

Wednesday, August 4, 2010

Import and Export .pst files Exchange 2010

Currently, Exchange 2010 SP1 is still in beta. Among other new features it’s not longer necessary to install Outlook 2010 (64 bit!!) on your Exchange 2010 server.
For now you have to.

To import or export .pst files you need to get the right Role Assignment. From the Exchange Management Shell:

New-ManagementRoleAssignment –Role “Mailbox Import Export” –User “Administrator”

Then it’s just a matter of:

Export-Mailbox Administrator -PSTFolderPath E:\

HOWEVER
If you have all the roles (Mailbox, Client Access and Hub Transport) on the same server, you’ll run into error:

Error occurred in the step: Approving object. An unknown error has occurred., error code: -2147221219

Solution:

  • Either move the Mailbox (+Outlook 2010 64bit) to a second Exchange server.
  • Or change the following:
    • adsiedit
    • connect to..
    • Well known Naming Context: Configuration
    • CN=Configuration,DC=your,DC=domain,DC=local
    • CN=Services,
    • CN=Microsoft Exchange,
    • CN=<Your Organization Name>,
    • CN=Administrative Groups,
    • CN=Exchange Administrative Group (FYDIBOHF23SPDLT),
    • CN=Databases,
    • CN=Mailbox Database 0123456789,
    • Now rightclick on “CN=Mailbox Database 0123456789” (left pane), properties
    • security tab
    • Grant the System user the following rights: Read, Administer information store, Allow Impersonation to Personal Exchange, Create named properties in the information store, Open mail send queue, Receive as, Send as, View information store status
    • Restart

This should be fixed in SP1 or even before that.