Archive

Archive for March, 2009

Using clusterssh to admin multiple service consoles

March 26th, 2009 Eric No comments

We have our service consoles set up to disallow root logins and use sudo (with password) for access. Every once in a while this causes us some pain. How do you update file /etc/filex or run some command across a cluster or a bunch hosts when root privileges are needed?

There are multiple ways to approach this type of issue, but one I have not seen much of in the VMware blogosphere is clusterssh. It allows you to interactively type commands on a number of hosts at the same time. If something sticks out you can enter commands on any of the individual boxes.

Some linux distributions include this in their repositories so it can be pretty easy to give it a try (something like apt-get install clusterssh to install). It supposedly works on OS X too.

Categories: System Administration, VMware Tags: ,

Using ScriptProperty members in PowerShell

March 25th, 2009 Eric No comments

I was looking for information on ScriptProperty members in PowerShell and was running into trouble finding anything useful. The PowerShell in Action book saved me on page 229.

Here is the object I am using in a piece of code that I am finishing for persisting server credentials to disk in a secure fashion. It shows a real world example of when a ScriptProperty is needed instead of the simpler NoteProperty.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
Function SecureCredentialStoreItem
{
    $item = New-Object PSObject
 
    # Hostname
    $item | Add-Member -MemberType NoteProperty -Name hostname -Value ""
 
    # Username portion of the credential
    $item | Add-Member -MemberType ScriptProperty -Name username -Value `
            { # Get
                $this.credential.username
            } `
            { # Set
 
                param
                (
                    [String]$username
                )
 
                # Username is read only so we create a replacement credential.
                $newCred = New-Object System.Management.Automation.PSCredential $username, $this.credential.password
                $this.credential = $newCred
            }
 
    # Password portion of the credential
    $item | Add-Member -MemberType ScriptProperty -Name password -Value `
            { # Get
                $this.credential.password
            } `
            { # Set
 
                param 
                (
                    [System.Security.SecureString]$password
                )
 
                # Password is read only so we create a replacement credential.
                $newCred = New-Object System.Management.Automation.PSCredential $this.credential.username, $password
                $this.credential = $newCred
            }
 
    # Credential
    $item | Add-Member -MemberType NoteProperty -Name credential -Value `
                       (New-Object System.Management.Automation.PSCredential "<empty>", 
                            (New-Object System.Security.SecureString))
 
    # In general I would recommend against using this, but there are times
    # when it must be done.  Done as a method so it is not run unless called
    # explicitly.  Setting should be done via the securestring password property.
    $item | Add-Member -MemberType ScriptMethod -Name passwordToPlainText -Value `
            {
                $ptr=[System.Runtime.InteropServices.Marshal]::SecureStringToCoTaskMemUnicode($this.credential.password)
                $str = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($ptr)
                [System.Runtime.InteropServices.Marshal]::ZeroFreeCoTaskMemUnicode($ptr)
                $str
            }
    $item
}
Categories: Uncategorized Tags:

VI SDK – Beware cached data and assumptions

March 23rd, 2009 Eric No comments

Applications often cache data and that is good because that generally makes them perform better for users. However, if you make assumptions that what you see is the absolute truth you can run into trouble.

Connect-ViServer myVirtualCenter001
 
# Let's check the status of the server to make sure I can go home.
(Get-vmhost myVmHost001.local | Get-View).OverallStatus
green
 
#Looks good.  Well, maybe not.
(Get-vmhost myVmHost001.local |Get-View).runtime.ConnectionState
disconnected

I know for a fact that this server is not even running VMware at this point so how could I get a green status? Caching. I am not saying that VMware is doing anything wrong in this case, but be aware that your view of the data may not be the most recent.

Always check your assumptions when the data matters.

Categories: Scripting, System Administration, VMware Tags:

Validating VM advanced settings

March 20th, 2009 Eric No comments

Now that we have covered how to make advanced settings changes we need to validate that the settings have been applied.  Assuming that a script or command worked is never as good as checking it.  Below is a script to do just that.

The script lists all statuses so if you only want to see issues you can pipe the output into the Where-Object cmdlet like so:

<vmObject(s)> | .\Validate-VmAdvancedSettings.ps1 | Where-Object {$_.Status -ne “Ok”}

The script:

# Usage: <vmobject> | .\Validate-VmAdvancedSettings.ps1
# Examples: Get-VM myTestVM | .\Validate-VmAdvancedSettings.ps1
#           Get-Cluster myCluster | Get-VM | .\Validate-VmAdvancedSettings.ps1
 
BEGIN
{
    # The settings as an array of arrays.  ("key", "value)
    $advancedSettings = @( ("isolation.tools.copy.disable", "true"),
                           ("isolation.tools.paste.disable", "true"),
                           ("isolation.tools.setGUIOptions.enable", "false"),
                           ("log.rotateSize", "100000"),
                           ("log.keepOld", "10"),
                           ("isolation.tools.connectable.disable", "true"),
                           ("isolation.device.connectable.disable", "true"),
                           ("isolation.tools.diskWiper.disable", "true"),
                           ("isolation.tools.diskShrink.disable", "true")
                         )
    $keyIndex = 0
    $valueIndex = 1
}
 
PROCESS
{                      
    $vmView = Get-View $_.Id
 
    # Get the existing settings in an easy lookup format.
    $vmSettings = @{}
    foreach ($item in $vmView.Config.ExtraConfig)
    {
        $vmSettings[$item.Key] = $item.Value
    }
 
    # Validate each of the advanced settings.
    foreach ($setting in $advancedSettings)
    {
        $status = $null
        if (!$vmSettings.ContainsKey($setting[$keyIndex]))
        {
            $status = "Missing"
        }
        elseif ($vmSettings[$setting[$keyIndex]] -ne $setting[$valueIndex])
        {
            $status = "Misconfigured"
        }
        else
        {
            $status = "Ok"
        }
 
        $vmView | Select-Object Name, 
                                @{Name="Setting"; Expression={$setting[$keyIndex]}},
                                @{Name="Status"; Expression={$status}}
    }
}
Categories: Scripting, System Administration, VMware Tags:

Making advanced settings changes to a running VM

March 19th, 2009 Eric No comments

If you use a method like that in the Powershell script I posted the changes can be made to a running VM. This is great because that dialog box is disabled in Virtual Center when the vm is up.

The settings do not take effect until the VM is power cycled (not just restarted in the OS).  This is not that big of a deal on clusters with VMotion licensed because a VMotion starts a new instance of the VM on the destination host.  I have validated that security settings like isolation.tools.connectable.disable work immediately after the VMotion, but I have not checked all settings.

As always, be careful with the advanced settings and be prepared with a backout plan before doing this on a large scale (i.e. before ESX host patching).

Let me know if you run into any settings that do not apply after a VMotion.

Categories: Scripting, System Administration, VMware Tags:

Version Control for (VMware) System Administrators

March 16th, 2009 Eric No comments

It has been long held that *nix administrators should use version control, but this knowledge has not really made it over to the Windows world where a lot of VMware administrators come from.

I consider version control for scripts and configuration files to be an essential part of any well run site. It is something that can be set up in a few hours (Window or *nix) and most admins will need to learn only the basics of the tools.

The benefits of version control are many, but here are the ones that stick out for me:

  • The ability to revert to a known good file if problems are encountered during a change.
  • Much more scalable than creating file.bak, file.bak001, file.bak002, etc.
  • A known good source to determine what has been modified in a file.
  • An authoritative source for files that can be made easily accessible via http or the version control tools.
  • The ability for multiple admins to work on scripts and track when and what changes were made.

Here is an article that was written for Login magazine that gives a good overview of the process.
Using Version Control in System Administration by Luke Kanies

Categories: Uncategorized Tags:

VMware Update Manager Profile Updates

March 13th, 2009 Eric No comments

I added these to my Powershell profile to make working with the VMware Update Manager Toolkit a little easier from my standard shell.

Add-PSSnapin VMware.VumAutomation
function Get-VumCommand {Get-Command -pssnapin VMware.VumAutomation}
Categories: Uncategorized Tags:

Get-AllRolePrivileges

March 12th, 2009 Eric No comments

This is a good script to easily report on privileges and can easily be extended to audit against a known good list of expected roles/privileges.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#Must already be connected to a viserver. This works on the default vi server.
$si = Get-View ServiceInstance
$am = Get-View ($si.Content.AuthorizationManager)
 
$roles = $am.RoleList
 
foreach ($role in $roles)
{
    foreach ($privilege in $role.Privilege)
    {
        $role| Select-Object RoleId, System, Name,
                             @{Name="Privilege"; Expression={$privilege}}
    }
}
Categories: Scripting, System Administration, VMware Tags:

Script for VM advanced settings

March 11th, 2009 Eric No comments

I created this one so I could easily apply multiple advanced settings to a list of VMs. The $advancedSettings array is easily modified to change what get configured.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# Usage: <vmobject> | .\Configure-VmAdvancedSettings.ps1
# Examples: Get-VM myTestVM | .\Configure-VmAdvancedSettings.ps1
#           Get-Cluster myCluster | Get-VM | .\Configure-VmAdvancedSettings.ps1
 
BEGIN
{
    # The settings as an array of arrays.  ("key", "value)
    $advancedSettings = @( ("isolation.tools.copy.disable", "true"),
                           ("isolation.tools.paste.disable", "true"),
                           ("isolation.tools.setGUIOptions.enable", "false"),
                           ("log.rotateSize", "100000"),
                           ("log.keepOld", "10"),
                           ("isolation.tools.connectable.disable", "true"),
                           ("isolation.device.connectable.disable", "true"),
                           ("isolation.tools.diskWiper.disable", "true"),
                           ("isolation.tools.diskShrink.disable", "true")
                         )
    $keyIndex = 0
    $valueIndex = 1
}
 
PROCESS
{                      
    $vmView = Get-View $_.Id
    $vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
 
    foreach ($setting in $advancedSettings)
    {
        $vmConfigSpec.extraconfig += New-Object VMware.Vim.optionvalue
        $vmConfigSpec.extraconfig[-1].Key = $setting[$keyIndex]
        $vmConfigSpec.extraconfig[-1].Value = $setting[$valueIndex]
    }
    $vmView.ReconfigVM($vmConfigSpec)
}
Categories: Uncategorized Tags:

Script to update tools in templates.

March 10th, 2009 Eric No comments

Here is a script that takes template objects and updates their VMware tools.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# Usage: <template object(s)> | .\Upgrade-ToolsTemplate.ps1
# Example: Get-Template template1 | .\Upgrade-ToolsTemplate.ps1
#          Get-Datacenter corporate | Get-Template | .\Upgrade-ToolsTemplate.ps1
# Note: When getting template make sure to get the correct datacenter in case
#       there are duplicate names.
 
BEGIN
{
    $sleeptime = 60
}
 
PROCESS
{
    "Converting {0} to VM" -f $_.Name
    $vm = $_ | Set-Template -ToVM
 
    "Powering on the VM: {0}" -f $vm.Name
    $vm | Start-VM | Out-Null
 
    #TODO: Find a better way of doing this than just sleeping.  Perhaps poll 
    #      on tools status.
    "Sleeping for $sleeptime seconds"
    Start-Sleep -Seconds $sleeptime
 
    $vmview = Get-View $vm.ID
    "Existing Tools Version {0}" -f $vmview.config.tools.toolsVersion
 
    "Upgrading Tools"
    $vm | Update-Tools
 
    "Sleeping for $sleeptime seconds"
    Start-Sleep -Seconds $sleeptime
 
    $vmview = Get-View $vm.ID
    "New Tools Version {0}" -f $vmview.config.tools.toolsVersion
 
    "Powering off the VM: {0}" -f $vm.Name
    $vm | Stop-VM -confirm:$false | Out-Null
 
    "Converting to template"
    $vmview.MarkAsTemplate()
}
Categories: Scripting, System Administration, VMware Tags:

Switch to our mobile site