Thursday, September 23, 2010

Export and Import VMware affinity rules

More searching for migration of my VCenter and I found http://ict-freak.nl/2009/09/06/powercli-export-and-import-drs-rules-v2/ which allows me to export and import the affinity rules


Export

Get-Cluster -Name "TUK_UT_04" | Get-DrsRule | `
Export-CliXml 'd:\temp\AffinityRules.xml' 

Import

ForEach ($rule in (Import-CliXml 'd:\temp\AffinityRules.xml')){
    New-DrsRule -Cluster (Get-Cluster -Name "TUK_UT_04") `
    -Name $rule.Name -Enabled $rule.Enabled `
    -KeepTogether $rule.KeepTogether `
    -VM (Get-VM -Id $rule.VmIds)} 

Export and Import VMware customization specs

While looking for ways to migrate to our new VCenter server, I came across http://www.van-lieshout.com/2009/07/export-and-import-customization-profiles-using-powershell/ which describes how to export your customization specs (passwords and all) and then reimport them into the new VC.


Export
$path="d:\temp"
#Export Customization Profiles
$view = get-view CustomizationSpecManager
ForEach ($CustomizationProfile in $view.info) {
    $xml = $view.CustomizationSpecItemToXml($view.GetCustomizationSpec($CustomizationProfile.name))
    $xml | Out-File ($path + "\" + ($CustomizationProfile.name) + ".xml")
}

Import
$path="d:\temp"
#Import Customization Profiles
$view = Get-View CustomizationSpecManager
ForEach ($xmlfile in (Get-ChildItem -Path $path | where {$_.extension -eq ".xml"})) {
    $xml = Get-Content ($xmlfile)
    $view.CreateCustomizationSpec($view.XmlToCustomizationSpecItem($xml))
}

Script to migrate to new VCenter

We are looking at building a new VCenter on new x64 hardware with a new DB server and were struggling with how to migrate our environment from one server to the other. Thanks to the script at http://technodrone.blogspot.com/2010/01/vcenter-powercli-migration-script.html, it looks like this may be an easy task.
It appears that some properties (such as affinity rules) arent copied over, but its a darn good start.

Monday, September 20, 2010

TSQL script to shrink all log files

I got alerted over the weekend to a SQL server running out of disk space on one of its drives. Upon further inspection, several of the LOG files had grown and were filling the log drive. I went to shrink the files, but realized there must be a better way.

A little googling and I found http://codesnippets.joyent.com/posts/show/665. This script cycles through all DBs and shrinks the LOG files for each DB. Simply schedule it with the SQL Server Agent and your good to go.


declare @ssql nvarchar(4000)
set @ssql= '
        if ''?'' not in (''tempdb'',''master'',''model'',''msdb'') begin
        use [?]
        declare @tsql nvarchar(4000) set @tsql = ''''
        declare @iLogFile int
        declare LogFiles cursor for
        select fileid from sysfiles where  status & 0x40 = 0x40
        open LogFiles
        fetch next from LogFiles into @iLogFile
        while @@fetch_status = 0
        begin
          set @tsql = @tsql + ''DBCC SHRINKFILE(''+cast(@iLogFile as varchar(5))+'', 1) ''
          fetch next from LogFiles into @iLogFile
        end
        set @tsql = @tsql + '' BACKUP LOG [?] WITH TRUNCATE_ONLY '' + @tsql
        --print @tsql
        exec(@tsql)
        close LogFiles
        DEALLOCATE LogFiles
        end'

exec sp_msforeachdb @ssql

Thursday, September 16, 2010

Executing commands in a VM via powershell

I got to thinking today that when you tell a VM to shutdown the OS, it is actually executing a command against the VM itself, not just in VMware. I decided to do a little searching to see what it takes to do something similar with other commands (such as srvinfo, or listing disk usage) and started googling.
I came across this interesting post that describes how to change a VMs IP address using the Invoke-VMScript powershell command.http://www.virtu-al.net/2010/02/05/powercli-changing-a-vm-ip-address-with-invoke-vmscript/
A little more searching and I found the following page that lists several other powershell functions to interact with guest VMs. Copy-VMGuestFile and Invoke-VMScript are 2 particularly interesting ones.http://www.amikkelsen.com/?p=357

Wednesday, September 15, 2010

Powershell to disconnect CD and Floppy drives in ESX

This script will enumerate all VMs and disconnect all CDs and Floppy drives
get-cddrive -VM *  |where {$_.ISOPATH -ne $null}|set-cddrive  -nomedia -Confirm:$False
get-cddrive -VM *  |where {$_.HOSTDevice -ne $null}|set-cddrive  -nomedia -Confirm:$False

get-FloppyDrive -VM *  |where {$_.FloppyImagePath -ne $null}|set-FloppyDrive -nomedia -Confirm:$False
get-FloppyDrive -VM *  |where {$_.HOSTDevice -ne $null}|set-FloppyDrive -nomedia -Confirm:$False

Syntax highlighting in blogger

http://www.cyberack.com/2007/07/adding-syntax-highlighter-to-blogger.html

List of brushes http://alexgorbatchev.com/SyntaxHighlighter/manual/brushes/

Brush nameBrush aliasesFile name
ActionScript3as3, actionscript3shBrushAS3.js
Bash/shellbash, shellshBrushBash.js
ColdFusioncf, coldfusionshBrushColdFusion.js
C#c-sharp, csharpshBrushCSharp.js
C++cpp, cshBrushCpp.js
CSScssshBrushCss.js
Delphidelphi, pas, pascalshBrushDelphi.js
Diffdiff, patchshBrushDiff.js
Erlangerl, erlangshBrushErlang.js
GroovygroovyshBrushGroovy.js
JavaScriptjs, jscript, javascriptshBrushJScript.js
JavajavashBrushJava.js
JavaFXjfx, javafxshBrushJavaFX.js
Perlperl, plshBrushPerl.js
PHPphpshBrushPhp.js
Plain Textplain, textshBrushPlain.js
PowerShellps, powershellshBrushPowerShell.js
Pythonpy, pythonshBrushPython.js
Rubyrails, ror, rubyshBrushRuby.js
ScalascalashBrushScala.js
SQLsqlshBrushSql.js
Visual Basicvb, vbnetshBrushVb.js
XMLxml, xhtml, xslt, html, xhtmlshBrushXml.js

VBScript to list and change DNS settings on all domain computers

If you ever change your Domain Controllers / DNS servers, you need to ensure all clients begin accessing the new servers before the old are retired. For DHCP, this is easy by editing the DHCP scopes and waiting until all the clients have renewed. For staticly assigned IPs, this can become a problem.

Below is a script that searches AD for all domain computers and queries them via WMI for DNS settings on each NIC. If the SetDNSServerSearchOrder line is uncommented, it will reset the DNS configuration of the systems.


'QueryDNS.vbs

Const ADS_SCOPE_SUBTREE = 2
arrNewDNSServerSearchOrder = Array("10.10.52.14","10.10.52.15")

EnumComputers

SUB EnumComputers
    on error resume next
    strDomain = "mydomain.com"

    Set objConnection = CreateObject("ADODB.Connection")
    Set objCommand =   CreateObject("ADODB.Command")
    objConnection.Provider = "ADsDSOObject"
    objConnection.Open "Active Directory Provider"

    Set objCOmmand.ActiveConnection = objConnection
    objCommand.CommandText = "Select Name, Location, whenChanged from 'LDAP://" & strDomain & "' Where objectCategory='computer'"  
    objCommand.Properties("Page Size") = 1000
    objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE 
    Set objRecordSet = objCommand.Execute
    objRecordSet.MoveFirst

    Do Until objRecordSet.EOF
        dLastChanged = objRecordSet.Fields("whenChanged").Value
        serverName = objRecordSet.Fields("Name").Value
        if dLastChanged>now()-60 THEN 
            QueryDNS serverName
        END IF
            objRecordSet.MoveNext
    Loop
END SUB

SUB QueryDNS(strServerName)
    on error resume next
    Set objWMIService =    GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strServerName & "\root\cimv2")
    'Set colNICConfigs = objWMIService.ExecQuery("SELECT DNSServerSearchOrder, Description FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = True AND DHCPEnabled = false")
    Set colNICConfigs = objWMIService.ExecQuery("SELECT    DNSServerSearchOrder, Description FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = True")
    for each objNICConfig in colNICConfigs
        OldDNSConfiguration = Join(objNICConfig.DNSServerSearchOrder, ",")
        if LEN(OldDNSConfiguration)>1 THEN
            wscript.echo strServerName &","& OldDNSConfiguration
            'objNICConfig.SetDNSServerSearchOrder(arrNewDNSServerSearchOrder)    ' Uncomment to reset DNS servers
        end if
    next
END SUB

VBScript to list the OS Version of all computers in domain

In a large environment, inventory information can quickly be out of date. Below is a script that searches AD for all computers and then reports the OS from each system. The OS information comes from the target computer, so firewalls and power state is important.


'OSVersion.vbs

on error resume next

Const ADS_SCOPE_SUBTREE = 2
strDomain = "mydomain.com"

Set objConnection = CreateObject("ADODB.Connection")
Set objCommand =   CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"

Set objCOmmand.ActiveConnection = objConnection
objCommand.CommandText = "Select Name, Location from 'LDAP://" & strDomain & "' Where objectCategory='computer'"  
objCommand.Properties("Page Size") = 1000
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE 
Set objRecordSet = objCommand.Execute
objRecordSet.MoveFirst

Do Until objRecordSet.EOF
    QueryServer objRecordSet.Fields("Name").Value
    objRecordSet.MoveNext
Loop


SUB QueryServer(strServer)
on error resume next
    Set objWMI = GetObject("winmgmts:" & "{impersonationLevel=impersonate,(Security)}!\\" & strServer & "\root\cimv2")
    SET objOSs = objWMI.ExecQuery("select * from Win32_OperatingSystem")
    For Each objOS in ObjOSs
        strCaption = objOS.Caption
        strBuildNumber = objOS.BuildNumber
        wscript.echo strServer & "," & strCaption' & " - " & strBuildNumber
        NEXT

END SUB 

VBScript to list file owner and other attributes

Occasionally I need to look at the owner of a file or group of files. The below script helps me enumerate a folder and list the file attributes


'GetOwner.vbs

Set objShell = CreateObject ("Shell.Application")
Set objFolder = objShell.Namespace ("D:\tools\AD")
Set objFSO = CreateObject("Scripting.FileSystemObject")

Dim arrHeaders(13)
For i = 0 to 13
    arrHeaders(i) = objFolder.GetDetailsOf (objFolder.Items, i)
Next
For Each strFileName in objFolder.Items
    For i = 0 to 13
        If i <> 9 then
            Wscript.echo arrHeaders(i)     & ": " & objFolder.GetDetailsOf (strFileName, i)
        End If
    Next
    Wscript.Echo
Next

VBScript to enumerate domain computers

Ever need to list all the computers in your Active Directory? This handy script will query AD and return all computer objects. A little tweaking and you can search for objects based on last modified time to ensure you are listing valid AD objects.



'EnumComputers.vbs

Const ADS_SCOPE_SUBTREE = 2
strDomain = "mydomain.com"

Set objConnection = CreateObject("ADODB.Connection")
Set objCommand =   CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"

Set objCOmmand.ActiveConnection = objConnection
objCommand.CommandText = "Select Name, Location from 'LDAP://" & strDomain & "' Where objectCategory='computer'"  
objCommand.Properties("Page Size") = 1000
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE 
Set objRecordSet = objCommand.Execute
objRecordSet.MoveFirst

Do Until objRecordSet.EOF
    wscript.echo objRecordSet.Fields("Name").Value
'    Wscript.Echo "Computer Name: " & objRecordSet.Fields("Name").Value
'    Wscript.Echo "Location: " & objRecordSet.Fields("Location").Value
    objRecordSet.MoveNext
Loop

VBScript to query NT Event Log in last X minutes

Occasionally I have a need to query NT Event Logs on several systems for an error within the last few minutes/hours/days. I adapted some online sources and created a handy VBScript using WMI that searches remote systems for an eventID in a specified period of time.



serverName=wscript.arguments(0)
EventID=wscript.arguments(1)
SearchMinutes=wscript.arguments(2)

QueryServer serverName, EventID, SearchMinutes

SUB QueryServer(strServer, eventID, minutes)
    on error resume next
    oldDate = DateAdd("n", -1 * minutes, now())
    myDate = DatePart("yyyy",oldDate) & Right("00" & DatePart("m",oldDate),2) & Right("00" & DatePart("d",oldDate),2) & "000000.0-420"

    ' ----------------------------------------------------------
    ' WMI Core Section 
    Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strServer & "\root\cimv2")
    strQuery = "select * from Win32_NTLogEvent where logfile='System' and TimeGenerated > '" & myDate & "' and (EventCode='"& eventID &"')"
    SET colLoggedEvents = objWMI.ExecQuery(strQuery)
    ' ----------------------------------------------------------
    ' Next section loops through ID properties

    For Each objItem in colLoggedEvents
        insString=  "TimeGenerated='" & objItem.TimeGenerated & "' ComputerName='" & objItem.ComputerName & "'  EventCode='" & objItem.EventCode & "' "
        strMessage = Replace(objItem.Message,vbCrLf & vbCrLf,vbCrLf)
        strMessage = Replace(strMessage,vbTab & vbTab,vbTab)
        strMessage = Replace(strMessage,"\n\n","\n")
        for each strIns in Split(strMessage, vbCrLf)
            if InStr(strIns, vbTab) then
                strIns = Replace(strIns,vbTab,"")
                strAtt = Replace(Split(strIns,":")(0)," ","_")
                strVal = Trim(Split(strIns,":")(1))
                strTmp = " " & strAtt & "='" & strVal & "' "
                if strTmp <> " ='' " THEN insString = insString & strTmp
                strAtt=""
                strVal=""
                strTmp=""
            end if
        NEXT

        wscript.echo insString
        insString=""
    Next
END SUB


Find MAC addresses used in VMware

The following 1 line powershell commands will help you find all the MAC addresses used in VMware for the VMs and VMKernel nics.

List all ESX host MAC addresses
get-vmhost | get-vmhostnetworkadapter | export-csv d:\temp\VMHost.csv

List all guest VM MAC addresses
get-vm | get-networkadapter | export-csv d:\temp\VMAdapter.csv

Use SNMP to find a device on Cisco

In my recent search for a rouge MAC address, I had dozens of Cisco switches to look through in order to find the port the address came from. I vaguely remembered hearing about someone using SNMP to track a MAC down to a specific port on a switch, and decided to take a look.

I found http://www.cisco.com/en/US/tech/tk648/tk362/technologies_tech_note09186a00801c9199.shtml which detailed the process of finding the port owner of a MAC via SNMP. A summary of steps are below:

  • From Step 1, the MAC address is:
    17.4.3.1.1.0.0.12.7.172.8 = Hex: 00 00 0C 07 AC 08
  • From Step 2, the bridge port tells that the MAC address belongs to bridge port number 13:
    17.4.3.1.2.0.0.12.7.172.8 = 13 
  • From Step 3, the bridge port number 13 has ifIndex number 2:
    17.1.4.1.2.13 = 2
  • From Step 4, the ifIndex 2 corresponds to port Fast Ethernet 0/1:
    ifMIB.ifMIBObjects.ifXTable.ifXEntry.ifName.2 = Fa0/1

MAC address 00:50:56:50:00:00 -- Beacon Probing

We had an unusual network issue the other day and as part of it we were told that two devices were reporting the same MAC address - 00:50:56:50:00:00. The address manufacturer is VMware, which suggested it was a VM or VMKernel interface.

I searched through the entire VC and was unable to find the MAC anywhere. I looked at the MAC/CAM tables of our switches and was able to confirm it existed (0050.5650.0000), but couldn't track down the owner. Because the address looked so unusual, I even Googled it and failed to find anything.

In order to isolate the address, I decided to change our active/passive load balancing on some of our hosts to use the passive link. This way, if the MAC address stopped showing on switchA and started showing on switchB, I could identify the culprit.

As I was moving some of the vnics, I realized that some of our vSwitches were set to use Beacon Probing. Since our standard config is to use Link State, I change the setting and then reviewed our switches. The mystery MAC address immediately disappeared. I re-enabled Beacon Probing to be sure, and watched the MAC reappear, disabled and it disappears.

Tuesday, September 14, 2010

Change VLAN of a PortGroup in VMware

We recently had a need to change the VLAN of a port group in our ESX clusters. We could have run the sync script to replicate all the changes, but that potentially touches so much that I didnt want too. I instead used the below commands in powershell to search for a port group and then change the VLAN.




$ESXHosts = Get-VMHost
foreach ($ESXHost in $ESXHosts){
$VirtualSwitches = Get-VirtualSwitch -VMHost $ESXHost
foreach ($VirtualSwitch in $VirtualSwitches){
$VirtualPortGroups = Get-VirtualPortGroup -VirtualSwitch $VirtualSwitch
foreach ($VirtualPortGroup in $VirtualPortGroups){
if (($VirtualPortGroup).Name -eq "portgroup_25") {
write-host $VirtualPortGroup.Name
write-host $VirtualPortGroup.VLanId
#Set-VirtualPortGroup -VirtualPortGroup $VirtualPortGroup -VLanId 25
}
}
}
}

Monday, September 13, 2010

Reset Directory Services Restore Mode Password


If the Directory Services Restore Mode password is unknown, follow these steps to reset it to a known value. NOTE: Directions for Windows 2003 only.
  1. Open a command prompt and type ntdsutil.exe
  2. Start the Directory Service Restore Mode Administrator password-reset utility by typing set dsrm password
  3. Run the Reset Password command, passing the name of the server on which to change the password, or use the null argument to specify the local machine.
    To reset the password on the local machine, specify null as the server name:
    Reset DSRM Administrator Password: reset password on server null
  4. You'll be prompted twice to enter the new password. You'll see the following messages:
    Please type password for DS Restore Mode Administrator Account:
    Please confirm new password:
    Password has been set successfully.
  5. Exit the password-reset utility by typing quit twice
  6. Reboot the server