Categories
Backups

VMWare : VCB Cleanup Script

VMWare : VCB Cleanup Script

VCB is a powerful and useful technology for backing up Virtual Machines running on ESX/vSphere, more than once it has rescued an entire Virtual Machin where a standalone server would have had to be rebuilt.

My only fault with the ‘vanilla’ installation is the cleanup process. Whena  VCB backup fails, or even succeeds at times, the snapshot is not cleaned up on the VCB proxy server or the ESX host. This can result in wastedstorage on both systems.

VCB includes a cleanup script which will clean directories in the VCB root folder as specified in the following file: C:\Program Files\VMware\VMware Consolidated Backup Framework\config\config.js

This script works well at cleaning up folders for VCB that are created dynamically in the root folder, however, if you have created subdirectories for per-VCB tasks the script will not automatically cleanup the VCB snapshots. I create a sub-folder on a per-VCB basis, why? This is simple,. because using HP dataprotector to perform VCB backups I have to specify a folder that exists tobackup to tape. If I specify the VCB root folder then if a VCB fails and the data is not cleaned up, the next VCB will be significantly larger as it will contain the data for the failed VCB snapshot and the new VCB snapshot.

I have around 50 VM’s, therefore manually editing the VCB config.js file to reflect the root VCB directory for each backup was a no-no.

You’ll find a link below to a modified version of the vcb-cleanup.wsf file included with the VCB proxy package. Copy this file to the ‘C:\Program Files\VMware\VMware Consolidated Backup Framework\generic’ directory.

Modify the  C:\Program Files\VMware\VMware Consolidated Backup Framework\config\config.js file to reflect the root cotainer for all of your VCB folders.

Follow the steps outlined below to perform VCB cleanup on all subfolders:

  1. Ensure no VCB backups are in progress
  2. Open a command prompt, cd to  “C:\Program Files\VMware\VMware Consolidated Backup Framework\generic”
  3. Execute the following command “cscript.exe vcb-cleanup-mod.wsf “C:\Program Files\VMware\VMware Consolidated Backup Framework”  -y”

Download the script from here. Not, you will need to rename the file from ‘.txt‘ to ‘.wsf

In order for VCB to work under Windows 2008 R2 x64 you must configure vcbMounter.exe to “Run As Administartor”

Categories
Domain Migration

Migration : SIDHistory Cleanup vbScript

Migration : Cleanup SIDHistory

One of the last steps in an Actiove Directory migration is the removal of SIDHistory from migrated users, computers and groups. This will help reduce the size of the directory database.

Before cleanup of SIDHistory domain-wide, you should perform cleanup on a single OU and analyse the effects on applications such as AzMan and Sharepoint. Watch out for DCOM remote launch pernmissions. It is possible to modify the script to target individual users for this purpose.

The following VBScript will perform a SIDHistory cleanup of all user objects (this can be altered) within a particular OU. It is possible to change the LDAP filter and OU string to suit testing and cleanup of various object classes. Alternately, by changing the line strOU = “OU=UK,” to strOU = “” willl perform SIDHistory cleanupon all objects within every OU.

Remember to perform cleanup on the following objectClass types, changing the code in RED will allow you to perform cleanup of different objectClass’: User, Computer, Contact, Group.

   Const ADS_PROPERTY_DELETE = 4
   Const ADS_PROPERTY_UPDATE = 2

   Dim strFilter ‘As String
   Dim oConnection ‘As ADODB.Connection
   Dim oRecordSet ‘As ADODB.RecordSet
   Dim strQuery ‘As String
   Dim strDomainNC ‘As String
   Dim oRootDSE ‘As IADs
   Dim vArray ‘As Variant()
   Dim vSid ‘As Variant
   Dim oDirObject ‘As Variant
   Dim strOU ‘As String

   ‘ Find the domain naming context
   set oRootDSE = GetObject(“LDAP://RootDSE”)
   strDomainNC = oRootDSE.Get(“defaultNamingContext”)
   set oRootDSE = Nothing

   ‘ Setup the ADO connection
   Set oConnection = CreateObject(“ADODB.Connection”)
   oConnection.Provider = “ADsDSOObject”
   oConnection.Open “ADs Provider”
   
   ‘Target OrganizationalUnit
   strOU = “OU=UK,”
   
   ‘Target objectClass
   strFilter = “(&(objectClass=user))”
   strQuery = “;” & strFilter & “;distinguishedName,objectClass,name,sidHistory;subtree”

   ‘Execute the query
   set oRecordSet = oConnection.Execute(strQuery)

   if oRecordSet.Eof then
     WScript.Echo “No objects were found”
     WScript.Quit(0)
   Else
     Dim vClasses ‘As Variant
     Dim strClass ‘As String

     WScript.Echo “Name, Class, DN, SIDHistory”

     ‘ Iterate through the objects that match the filter
     While Not oRecordset.Eof
        vClasses = oRecordset.Fields(“objectClass”).Value
        strClass = vClasses(UBound(vClasses))
       
        If IsNull(oRecordSet.Fields(“sIDHistory”).Value ) Then
           WScript.Echo “This object does not have a sidHistory”
        Else
            set oDirObject = GetObject(“LDAP://” & oRecordset.Fields(“distinguishedName”).Value)
               vArray = oDirObject.GetEx(“sIDHistory”)
              
             For Each vSid in vArray
                   If OctetToHexStr(vSid) > “” Then
                       WScript.Echo chr(34) & oRecordset.Fields(“name”).Value & chr(34) & “,” & _
                        chr(34) & strClass & chr(34) & “,” & chr(34) & _
                        oRecordset.Fields(“distinguishedName”).Value & chr(34) & “,” & chr(34) & _
                        OctetToHexStr(vSid)    & chr(34)
                End If
            Next

            oDirObject.SetInfo
            WScript.Echo “The sidHistory has been cleared for this object!”
        End if
        WScript.Echo
        oRecordset.MoveNext
     Wend
   End if

   ‘Clean up
   Set oRecordset = Nothing
   Set oConnection = Nothing

Function OctetToHexStr(sOctet)
  Dim k
  OctetToHexStr = “”
  For k = 1 To Lenb(sOctet)
    OctetToHexStr = OctetToHexStr _
      & Right(“0” & Hex(Ascb(Midb(sOctet, k, 1))), 2)
  Next
End Function

Categories
Windows Server 2003

Windows 2003 Cluster :  MPIO Issues

Windows 2003 Cluster :  MPIO Issues

I came across an odd issue not that long ago, with an Exchange 2007 SP1 CCR cluster running on Windows Server 2003 R2 SP2 x64.Hardware specifications for this issue were as follows:

  • The hardware was HP C-Class BL680c Blades in a C7000 chassis.
  • Network connectivity for the chassis was handled by dual HP Virtual Connect (VC) modules
  • Fibre connectivity supplied by HP VC 4G/B Fibre Modules using NPIV.
  • Approx 25 EVA 3000 disks were presented to each node, the HP EVA DSM was installed on the cluster nodes.

Symptoms

The following events would be reported in the event log:

  • Event ID 129  : ql2300 Warning “Reset to device, \Device\RaidPort0, was issued
  • Event ID 11    : ql2300 Error “The driver detected a controller error on \Device\RaidPort0.”

  

With no patter, or discernable cause the cluster would either:

  • Fail-over to the passive node.
  • The cluster service on the passive node woud stop, along with all Exchnage resources

This would happen several times a week.

The following events would be logged in the event log:

  • Event ID 1118  : clusNet Error “Cluster service was terminated as requested by Node 1.”
  • Event ID 1026 : hpevadsm Error “The Driver has detected a path failur/removal to LUN ID

  

Fainlly, MPIO errors were logged in the event log and disk paths would be missing:

  • Event ID 17 : mpio Warning \Device\MPIODisk1 is currently in a degraded state. Once or more paths have failed, thoughthe process is now complete.
  • Event ID 16 :mpio Warning “A fail-over on\Device\MPIODisk24 occurred”

  

These errors would be rported for multiple EVA disks at a time.

Cause

This is caused by thethe HP VC module firmware versions (both the Ethernet and F/C modules require updating – however this entails several more updates!)

Solution

  1. Update all of the individual server firmware in the chassi using the HP Firmware Maint. CD 
  2. Update the HP Onboard Administrator
  3. Update th HP Virtual Connect Modules

 Since following this ‘action plan’ from HP the issue wasresolved – no re-occurance in 7 weeks.

 

 

 

 

Categories
SQL

SQL 2008 : “Invoke or BeginInvoke” SP1 Error

SQL 2008 : “Invoke or BeginInvoke” SP1 Error

I recently came across an error when installing SP1 on a Windows 2008 R2 x64/SQL 2008 Standard x64 environment which prevened me from installing the service pack:

“Invoke or BeginInvoke cannot be called on a control until the window handle has been created.”

As a work around I identified that I was able to right-click the update and select ‘Run as Administrator.’ I was then able to complete the update without issue.

Categories
Windows Server 2003

Powershell : Export Active Directory Group Members

Powershell : Export Active Directory Group Members

First you will need to obtain the ‘ActiveRoles Management Shell for Active Directory’ from the following link: http://www.quest.com/powershell/activeroles-server.aspx

Next save the following code into a new ‘.ps1’ script file:

$data = @()
foreach ($grp in Get-QADGroup -SearchRoot “internal.local/UK” | select-object Name,DN ) {$data += get-qadgroupmember -identity $grp.DN | select @{n=”GroupName”;e={$grp.Name}},@{n=”GroupDN”;e={$grp.DN}},Name,@{n=”DistinguishedName”;e={$_.DN}},type}

$data | sort-object “GroupName” | export-csv C:\UK_GroupExport.csv

Modify the search root so that it reflects the domain name/OU you wish to enumerate groups and group members from. This should be in canonical form, for example “my.domain/myOU”.

On execution, this script will create a new csv file containing groups and all members, including nested groups.

Categories
Exchange Server 2007

Exchange 2007 : Mailbox Statistics and Storage Quotas

Exchange 2007 : Mailbox Statistics and Storage Quotas

Usethe following Exchange Shell command to list all mailboxes, sorted by size

get-mailbox | Get-MailboxStatistics |  Select @{n=”DisplayName”;e={$_.DisplayName}}, StorageGroupName,@{e={$_.TotalDeletedItemSize.Value.ToMB()};n=”TotalDeletedItemsSize(MB)”}, DeletedItemCount, @{e={$_.TotalItemSize.Value.ToMB()};n=”TotalItemSize(MB)”}, ItemCount, StorageLimitStatus | Sort-Object “TotalItemSize(MB)” | ft

Use the following command to list all mailboxes with a StorageQuotaStatus of ‘ProhibitSend’

get-mailbox  | Get-MailboxStatistics | where-object {$_.StorageLimitStatus -eq “ProhibitSend”} |  Select @{n=”DisplayName”;e={$_.DisplayName}}, StorageGroupName,@{e={$_.TotalDeletedItemSize.Value.ToMB()};n=”TotalDeletedItemsSize(MB)”}, DeletedItemCount, @{e={$_.TotalItemSize.Value.ToMB()};n=”TotalItemSize(MB)”}, ItemCount, StorageLimitStatus | Sort-Object “TotalItemSize(MB)” | ft

Alternately you can export the results to a CSV file using the following command:

get-mailbox | Get-MailboxStatistics | where-object {$_.StorageLimitStatus -eq “ProhibitSend”} |  Select @{n=”DisplayName”;e={$_.DisplayName}}, StorageGroupName,@{e={$_.TotalDeletedItemSize.Value.ToMB()};n=”TotalDeletedItemsSize(MB)”}, DeletedItemCount, @{e={$_.TotalItemSize.Value.ToMB()};n=”TotalItemSize(MB)”}, ItemCount, StorageLimitStatus | Sort-Object “TotalItemSize(MB)” | Export-Csv C:\mailbox_stats.csv

The following options are available as StorageQuotaStatus:

  • IssueWarning
  • BelowLimit
  • ProhibitSend
  • MailboxDisabled
  • NoChecking

Simply modifiy the command as follows to change the data returned by the command:

get-mailbox | Get-MailboxStatistics | where-object {$_.StorageLimitStatus -eq “IssueWarning“} |  Select @{n=”DisplayName”;e={$_.DisplayName}}, StorageGroupName,@{e={$_.TotalDeletedItemSize.Value.ToMB()};n=”TotalDeletedItemsSize(MB)”}, DeletedItemCount, @{e={$_.TotalItemSize.Value.ToMB()};n=”TotalItemSize(MB)”}, ItemCount, StorageLimitStatus | Sort-Object “TotalItemSize(MB)” | Export-Csv C:\mailbox_stats.csv

Categories
Exchange Server 2007

Exchange 2007 : Purge Outbox Script

Exchange 2007 : Purge Outbox Script

I recently cam across an issue where users email was getting ‘stuck’ in their Outbox, despite being sent to the intended recipient. Some users had approx 95% of the mailbox Send limit in stuck email, so this problem was affecting their ability to work.

The following script helped me to identify that approx 4GB of data was stuck in user Outboxes across my Exchange environment. This will genetrate a CSV file containing the Outbox size for every mailbox in the Exchange Org. Save the following code to a ‘.ps1‘ file and call from the Exchange Shell:

$data = @()
foreach($mbx in Get-Mailbox -ResultSize unlimited) { $data += Get-MailboxFolderStatistics $mbx.identity -FolderScope ‘Outbox’ | select @{n=”DisplayName”;e={$mbx.DisplayName}},FolderPath,ItemsInFolder,@{n=”FolderSize(MB)”;e={$_.folderSize.toMB()}}}

$data | sort-object “FolderSize(MB)” –Descending | export-csv c:\Outbox_sizes.csv

Once I had identified the severity of the issue I wrote the following power shell script to purge all user Outboxes, exporting the to a PST file in case of any repercussion, note you will have to create the intended export folder prior to running this scrip. As before, copy the following command into a  ‘ .ps1‘ file and execute from the Exchange Shell:

foreach($mbx in Get-Mailbox -ResultSize unlimited){ Export-Mailbox -Identity $mbx.identity -IncludeFolders “\Outbox” -PSTFolderPath “C:\OutboxExport\” -DeleteContent -BadItemLimit 1000 -confirm:$false }

Categories
SQL

SQL : Find Current Database Name

SQL : Find Current Database Name

The following T-SQL will identify the name of the current Database and set the variable @dbname to the name of the database.

/* Establish Current Database Context */
declare @dbname varchar (200)
set @dbname = (SELECT DB_NAME())

This is useful when checking the existence of a table within the current database, for example:

IF object_id(@dbname +N’..tblFragStats’) IS NULL
    BEGIN
        CREATE TABLE tblFragStats (
           Date DATETIME, ObjectName CHAR (255), ObjectId INT,
           IndexName CHAR (255), IndexId INT,
           Lvl INT, CountPages INT,
           CountRows INT, MinRecSize INT,
           MaxRecSize INT, AvgRecSize INT,
           ForRecCount INT, Extents INT,
           ExtentSwitches INT, AvgFreeBytes INT,
           AvgPageDensity INT, ScanDensity DECIMAL,
           BestCount INT, ActualCount INT,
           LogicalFrag DECIMAL, ExtentFrag DECIMAL
            )
    END

This code will function on any version of Microsoft SQL, from 2000 SP4 onwards.

Categories
SQL

SQL : Move TempDB

 SQL : Move TempDB

The following transact-SQL will move the tempdb data and log files to a different physical loation. Simply modify the FILENAME paths to suit, adding additional files where appropriate for your environment.

USE master
GO
ALTER DATABASE tempdb
    MODIFY FILE (NAME = tempdev, FILENAME = ‘N:\Data\tempdb.mdf’)
GO
ALTER DATABASE tempdb
    MODIFY FILE (NAME = templog, FILENAME = ‘N:\Data\tempdb.ldf’)
GO

After completing this you will need to take the SQL instance offline and bring it back onlin.

Categories
VBScript

VBScript : Find Windows Hardware Architecture

VBScript : Find Windows Hardware Architecture

The following VBscript will establish whether the local system is x86 or x64 and enable you to execute further commands based upon this. Simply copy the code into a new .vbs file and add the additional steps within the if statement.

Set WshShell = WScript.CreateObject("WScript.Shell")
vArchitecture = WshShell.RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\PROCESSOR_ARCHITECTURE")

If vArchitecture = "AMD64" Then
   '64 bit OS
    wscript.echo "64-bit OS"
ElseIf vArchitecture = "x86" Then
  '32 bit OS
   wscript.echo "32-bit OS"
End If