Pages

7/30/2013

Powershell - Change Service Startup Type

Powershell: Change Windows Service Startup Type of Remote Server

Works with Powershell 1.0 & 2.0

 #Check Startup Type
 ($svc = Get-WmiObject Win32_Service -ComputerName $server -Filter "name='wuauserv'") | out-null
 if ($svc.StartMode -eq "Disabled") {
     "$server WSUS service changed to Automatic"
     $result=$svc.changestartmode("Automatic")
 }#end if

 #Backup Service Registry
 $result=([WmiClass]"\\$server\ROOT\CIMV2:Win32_Process").create("c:\windows\regedit /e c:\WSUS.REG HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\wuauserv")
 write $server "Backup Service Registry RESULT=" $result.returnvalue
 
 #Set Service as Delayed Start
 write $server "configure service"
 $key = "SYSTEM\CurrentControlSet\Services\wuauserv"
 $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $server)
 $regKey = $reg.OpenSubKey($key, $true)
 $result = $regKey.setvalue("DelayedAutoStart", "1", "DWORD")

7/26/2013

Powershell: Status of Windows Hotfix

Powershell: Check Status of Windows Hotfix


##################################################################################
#
#   check-hotfix.ps1
#
#       Confirm hotfix has been installed on all Windows2008 servers
#
#       Requires admin permission on every server
#
##################################################################################

$hotfix = "KB2520155"

$ServerList = ".\SUCCESS.TXT" #servers where hotfix is installed
$ErrorList = ".\ERRORS.TXT" #servers where hotfix is not installed
$ListFile = ".\SERVERS.TXT" #all the servers I checked
New-Item $ListFile -Type file -Force >$nul
New-Item $ServerList -Type file -Force >$nul
New-Item $ErrorList -Type file -Force >$nul

$today = get-date
$day = $today.Day
$mth = $today.Month
$year = $today.Year
$hour = $today.Hour
$min = $today.Minute
$sec = $today.Second
$date = "$year-$mth-$day-$hour$min$sec"

@"
$date
Servers Responding to PING
--------------------------------------------------------------------------
"@  | out-file -encoding ASCII -filepath $ListFile

@"
$date
Servers with hotfix $hotfix
--------------------------------------------------------------------------
"@ | out-file -encoding ASCII -filepath $ServerList

@"
$date
Servers without hotfix $hotfix
--------------------------------------------------------------------------
"@ | out-file -encoding ASCII -filepath $ErrorList


$List = ""

"Execution in progress..."

# Create $list of AD machine accounts for Windows Servers
$strCategory = "computer"
$strOS = "Windows*Server*2008*"
$objDomain = New-Object System.DirectoryServices.DirectoryEntry
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = $objDomain
$objSearcher.Filter = ("OperatingSystem=$strOS")
$colProplist = "dnshostname", "operatingsystem"
foreach ($i in $colPropList){$objSearcher.PropertiesToLoad.Add($i)}
$colResults = $objSearcher.FindAll()
foreach ($objResult in $colResults) {
    $objComputer = $objResult.Properties;
    $Server = $objComputer.dnshostname
    $OS = $objComputer.operatingsystem
    $Server = $Server -replace "\.usa\.DOMAIN\.com", ""
    $Server = $Server -replace "\s{2,}", ""
    $OS = $OS -replace "$([char]0x00AE)" , "" #remove "registered trademark" symbol
    if ($Server) {#skip null
        "$Server , $OS"
        if (Test-Connection -ComputerName $Server -quiet -count 1) {#PING OK
            "    Responds to PING"
            "$Server , $OS" | out-file -encoding ASCII -filepath $ListFile -append

            #Get Hotfix info
            $installed = get-wmiobject -class "Win32_QuickFixEngineering" -namespace "root\CIMV2" -computername $strComputer `
               -Filter "HotFixID='$hotfix'" 

            if ($installed) {
                "        $hotfix INSTALLED!"
                write-output "$Server , $OS" | out-file -encoding ASCII -filepath $ServerList -append
            }
            else {
                "        $hotfix NOT installed"
                write-output "$Server , $OS" | out-file -encoding ASCII -filepath $ErrorList -append    
            }

        }#end if PING OK, do nothing if PING fails
    }#if not null, do nothing if null
}#foreach

Untiny API Extract Service

Untiny Extract Service

I am annoyed by "tinyURL" translated links just on principle. But I think they also can present a greater security risk if they are used in a drive-by attack to make a site look less suspicious. Untiny! To extract original URLs from tiny ones -- http://www.untiny.com -- will translate these back to the original. Get text formatted translation: http://untiny.me/api/1.0/extract?url={URL TO TRANSLATE}&format=text. For example: http://untiny.me/api/1.0/extract?url=http://tiny.pl/htk&format=text

7/25/2013

Calculating IOPS Requirements

IOPS = input output operations per second
A measure of demand and a measure of capability.

IOPS Demand
Servers - perform monitoring, refer to os & app vendor information on requirements
Users (virtual desktop) - about 25 iops for a typical user running multiple apps at once, 2GB RAM, single CPU.

IOPS Capability
IOPS per disk = Rotational latency + Seek Latency / 1000

Disk Speed     Est IOPS
7200 rpm            75
10000 rpm          125
15000 rpm          175
SSD                    6000 (?)

Read vs Write
Typical average:
40% Read, 60% Write

RAID "Penalty"
Write operations to RAID disk arrays require additional io operations to write parity data.
see more at theithollow.com

RAID Level          Write i/o Penalty
     0                              1
     1                              2
     5                              4
     6                              6

Calculation of required capability to meet demand:
IOPS Required =
(IOPS Demand * Read i/o%) + (Target IOPS * Write i/o% * RAID Penalty)

Unfortunately, I don't find such a scientific way to factor in the affect of caching/etc.

For example
Demand = 25 iops
read% = 40, write% = 60
RAID 5

(25 * 0.40 + 25 * 0.60 / 4) = 70
** Nearly triple!

So for 1000 users generating 25000 iops, we need 70000 iops on the "back end."

70000/175 = 400 15K disks would be required - holy moly also see yellowbricks.com

7/19/2013

Powershell - Copy Files to all servers

Using Powershell to copy files to every server


##################################################################################
#
# Copy files to all servers with AD accounts that respond to PING
#
#   Requires admin permission on every server
#
##################################################################################

$file1="Windows6.1-KB2520155-x64.msu"
$file2="Windows6.1-KB2520155-x86.msu"
$ServerList = ".\SUCCESS.TXT"
$ErrorList = ".\ERRORS.TXT"
$ListFile = ".\SERVERS.TXT"
New-Item $ListFile -Type file -Force >$nul
New-Item $ServerList -Type file -Force >$nul
New-Item $ErrorList -Type file -Force >$nul
$List = ""

"Execution in progress..."

# Create $list of AD machine accounts for Windows Servers
$strCategory = "computer"
$strOS = "Windows*Server*"
$objDomain = New-Object System.DirectoryServices.DirectoryEntry
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = $objDomain
$objSearcher.Filter = ("OperatingSystem=$strOS")
$colProplist = "dnshostname"
foreach ($i in $colPropList){$objSearcher.PropertiesToLoad.Add($i)}
$colResults = $objSearcher.FindAll()
foreach ($objResult in $colResults) {
    $objComputer = $objResult.Properties;
    $Server = $objComputer.dnshostname
    $Server = $Server -replace "\.usa\.domain\.com", ""
    $Server = $Server -replace "\s{2,}", ""
    if ($Server) {#skip null
        $Server
        if (Test-Connection -ComputerName $Server -quiet -count 1) {#PING OK
            "    Responds to PING"
            $Server | out-file -encoding ASCII -filepath $ListFile -append
            #Copy Files
            copy-item c:\dns-msu -destination ("\\\\"+$Server+"\\C$") -recurse

            #Check File1
            if (-not(Test-path ("\\\\"+$Server+"\\C$\\dns-msu\\$file1"))) {
                "        FAIL: $file1"
                write-output "$Server - MISSING $file1" | out-file -encoding ASCII -filepath $ErrorList -append
            }
            else {
                "        SUCCESS:  $file1"
                write-output "$Server - OK $file1" | out-file -encoding ASCII -filepath $ServerList -append    
            }

            #Check File2
            if (-not(Test-path ("\\\\"+$Server+"\\C$\\dns-msu\\$file2"))) {
                "        FAIL: $file2"
                write-output "$Server - MISSING $file2" | out-file -encoding ASCII -filepath $ErrorList -append
            }
            else {
                "        SUCCESS:  $file2"
                write-output "$Server - OK $file2" | out-file -encoding ASCII -filepath $ServerList -append    
            }
        }#end if PING OK
        else {#PING FAIL
            "    Does not respond to PING"
            write-output "$Server - PING Failure" | out-file -encoding ASCII -filepath $ErrorList -append
        }#end else PING FAIL
    }#if null
}#foreach

How to use BGP to achieve Internet redundancy - TechRepublic

How to use BGP to achieve Internet redundancy - TechRepublic: How to use BGP to achieve Internet redundancy

The general steps for implementing BPG multihoming are:
  1. Obtain your ASN from ARIN.
  2. Identify your network block of IP addresses. If you own these, then you have the right to advertise them on the Internet through BGP. If you are borrowing these from your provider, then you must ask your provider for permission before advertising them through another provider.
  3. If you have a single provider, you are typically using a static route to connect to that provider. That provider is not sending you any BGP routes. Assuming that is true, you will have to request that your provider send you BGP routes. (Your provider will need to know your ASN and your remote router’s neighbor address. The neighbor is the IP address that your BGP process uses to communicate with.) Once you have the provider's BGP routes in your routing table and you are advertising your network to your provider through BGP, you can remove your static route and have your provider remove their static route.
  4. Next, assuming that you are multihoming on a single router, bring up your secondary provider. They can set it up so that they send you BGP routes. Again, they will need to know your ASN and your neighbor address.
  5. Within the BGP table (database) on your router, you will see the routes from each of your providers. The best route in BGP is the route with the shortest AS path. (If the AS paths are identical, there is a tiebreaking procedure, but this is normally not the case.) The route that has the shortest AS path will be placed in your router’s routing table.

BGP Route Convergence on the Internet

BGP Internet Route Convergence

If your network is multihomed -- How long does it take routes TO you to converge? These slides are very informative.  Wish I was in the classroom during this talk....

http://www.cs.northwestern.edu/~ychen/classes/cs450-05/lectures/BGP_Convergence.ppt

Powershell - DNS Check

Check DNS Resolution using Powershell


##########################################################################################
#
#    DNS-CHECK.PS1
#
##########################################################################################


$outfile = ".\results.txt"
$list = ".\LIST.TXT"
$names = Get-Content $list 

$today = get-date
clear-host
write "==========================================================================="
write "  $today"
write "  Checking DNS Resolution"

write "$today" | out-file -encoding ASCII $outfile 
foreach($name in $names) {
    write "---------------------------------------------------------------------------"
    write-host "  $name"
  try {[Net.DNS]::GetHostEntry($name) }
  catch {
   Write-host $server "    ERROR:  $name - NOT FOUND IN DNS"
  "ERROR:  $name - not resolved in DNS" | out-file -encoding ASCII $outfile -append 
    }
}#foreach server
write "==========================================================================="

#end

7/16/2013

VMWare Powershell NTP Service Setup

VMware Powershell NTP Service Setup


#####################################################################
#
#   Setup NTP on a new host
#

$vcs = Read-Host "vCenter"
$user = Read-Host "userid"
$pw = Read-Host "Password for $user" -AsSecureString
#convert $pw to plain text
    $pass = [Runtime.InteropServices.Marshal]::PtrToStringAuto(
        [Runtime.InteropServices.Marshal]::SecureStringToBSTR($pw))

connect-viserver -Server $vcs -User $user -Password $pass

$pass = " "
clear-host

foreach ($VMHost in (Get-VMHost -Name privh*)) {
"    $VMHost"
    $ntp=get-vmhostservice -vmhost $VMHost | Where {$_.Key -eq 'ntpd'}
"        $ntp"
   set-vmhostservice -hostservice $ntp -policy "automatic"
   restart-vmhostservice $ntp -confirm:$false
}

disconnect-viserver -confirm:$false

7/12/2013

Redundant Datacenter Connectivity

Datacenter Connectivity

Goals
  • Create redundant datacenters. For now, 2 of them.
  • Redundant, diverse, physical circuits/paths
  • Allow simple movement of services between datacenters => support the same IP address ranges in either location
An example:  http://connect.iltanet.org/ILTANET/Go.aspx?c=BlogViewer&BlogKey=d671b21d-b20a-4b07-84d5-3d4357723f0a

Issues/Discussion Items
Layer 2
to allow the same IP address ranges
  • Circuits are different vendors taking very different paths with unknown infrastructure in between the datacenters. A failure could occur within the service provider, but all my ports show "up." 
  • So, Spanning Tree and Port Channels will not work for "in between" failures
  • UDLD, Unidirectional Link Detection, doesn't seem work on a "virtual circuit" over a provider network like Metro Ethernet.
  • Cisco's OTV is supposed to accomplish a big part of this, but it seems that a much less overblown solution could at least provide the Layer 2 redundancy.

Routing Redundancy
  • For routing to work, the (outbound)default route must be configured to go out through the same datacenter where the inbound traffic will be arriving. 
  • So any kind of automatic redundancy that fails the inbound route to the secondary datacenter needs to also initiate a change to the default route of all machines in the "shared" networks.
  • A compromise would be a "one button push" method to switch inbound and outbound routing to change between datacenters.
  • Does OTV address this?
Nuts & Bolts

  • A traditional solution would possibly involve 2 circuits each with a router at each end.  L3 redundancy between the 2 links using HSRP/GLBP, some kind of IP tracking to expose a service provider outage, and somehow create L2 tunnels over each one and use them via a port aggregation at the core switch.  The question remains whether this solution can be designed to show a link as down even if the failure is in between.
  • There seems to be little in the way of configuration help or reference material for GRE/MGRE tunnels.  Even less for L2 tunneling.  I suppose the motivation for helping users do that is even less now that there is a nebulous thing called OTV that involves a big spend on monster Nexus 7K core switches.
  • I haven't been able to get into the guts of this and do any testing.  Thinking it through on paper I always get bogged down with the L2 tunnel.  A possible example L2TP configuration is:

Router A:

pseudowire-class test
encapsulation l2tpv3
protocol none
ip local interface Loopback0
!
interface Loopback0
ip address 1.1.1.1 255.255.255.255
!
interface FastEthernet0/1
description LAN
no ip address
speed 100
full-duplex
xconnect 2.2.2.2 1 encapsulation l2tpv3 manual pw-class test
l2tp id 1 2


Router B:

pseudowire-class test
encapsulation l2tpv3
protocol none
ip local interface Loopback0
!
interface Loopback0
ip address 2.2.2.2 255.255.255.255
!interface FastEthernet0/1
no ip address
duplex auto
speed auto
xconnect 1.1.1.1 1 encapsulation l2tpv3 manual pw-class test
l2tp id 2 1

Windows 8 Help

Thanks to: *the* Mark Minasi, http://www.minasi.com/newsletters/nws1307.htm

shortcut keys

  • Start Screen: to get there, press the key on your keyboard with the "Windows" flag. I'll type that as "[w]" from now on.
  • Desktop: [w]+d
  • Charms: [w]+c
  • Settings, the Metro-ish Control Panel: [w]+I
  • Lock Orientation so it doesn't jump between portrait and landscape with [w]+O
  • Explorer is a pain to get more than one window open at a time but [w]+E always brings up a new Explorer window
  • Many administrative tools can be accessed more quickly with [w]+x
  • The new Metro modern apps have a wonky menu structure so to see every option all at once, [w]+z

7/10/2013

Powershell: Count datastores on VMWare Hosts

Powershell: Count datastores on VMware Hosts

All the LUN mappings & datastore names need to match on all hosts in a cluster. I hope to someday script a more comprehensive comparison of datastores & names. However, a quick and dirty confirmation is to count the datastores that are connected on every host in each cluster. If they match, it at least gives me a warm feeling.

#####################################################################
#
#   
#        Gather count of LUNs/Datastores connected to all hosts
#

$vcs = Read-Host "vCenter"
$user = Read-Host "userid"
$pw = Read-Host "Password for $user" -AsSecureString
#convert $pw to plain text
    $pass = [Runtime.InteropServices.Marshal]::PtrToStringAuto(
        [Runtime.InteropServices.Marshal]::SecureStringToBSTR($pw))

connect-viserver -Server $vcs -User $user -Password $pass

$pass = " "

$today = get-date
$day = $today.Day
$mth = $today.Month
$year = $today.Year
$hour = $today.Hour
$min = $today.Minute
$sec = $today.Second
$date = "$year-$mth-$day-$hour$min$sec"
$outfile = ".\datastores-"+$vcs+"-"+$date+".csv"

clear-host

"Host-Name,Datastore-Count" | out-file $outfile -encoding ascii
foreach ($VMHost in (Get-VMHost -Location $Cluster)) {
"    $VMHost"
    $dstores = $VMHost | Get-Datastore
    $ds = $dstores.count
"        $ds"
    "$VMHost,$ds" | out-file $outfile -encoding ascii -append
}

disconnect-viserver -confirm:$false

Powershell: VMware guest inventory

Powershell: VMware Guest Inventory

Gather information from vCenter server about VM's. In this case I was looking for machines that were connected to more than one network or datastore.

$vcs = Read-Host "vCenter"
$user = Read-Host "userid"
$pw = Read-Host "Password for $user" -AsSecureString
#convert $pw to plain text
    $pass = [Runtime.InteropServices.Marshal]::PtrToStringAuto(
        [Runtime.InteropServices.Marshal]::SecureStringToBSTR($pw))

#$vcon = Disconnect-VIServer * -Confirm:$False
$vcon = connect-viserver -Server $vcs -User $user -Password $pass

$pass = " "
$outfile = ".\"+$vcs+"-info.csv"

$reportedvms=New-Object System.Collections.ArrayList
$vms=get-view -viewtype virtualmachine | Sort-Object -Property {$_.Config.Hardware.Device | where {$_ -is [VMware.Vim.VirtualEthernetCard]} | Measure-Object | select -ExpandProperty Count} -Descending
 
foreach($vm in $vms){
$status = $vm.name
"    $status"
    $reportedvm = New-Object PSObject
    $ipnum = ($vm.guest.net | select IPaddress).IPaddress| out-string
    $path = $vm.name
    $current = get-view $vm.parent
      do {
        $parent = $current
         if($parent.Name -ne "Datastore*"){$path =  $parent.Name + "\" + $path}
         $current = Get-View $current.Parent
      } while ($current.Parent -ne $null)
    
    Add-Member -Inputobject $reportedvm -MemberType noteProperty -name Path -value $path
#    Add-Member -Inputobject $reportedvm -MemberType noteProperty -name Guest -value $vm.Name
    Add-Member -Inputobject $reportedvm -MemberType noteProperty -name Networks -value $($vm.network.count)
    Add-Member -Inputobject $reportedvm -MemberType noteProperty -name Network -value $((get-view $vm.network).name)
    Add-Member -Inputobject $reportedvm -MemberType noteProperty -name IP -value $ipnum
    Add-Member -Inputobject $reportedvm -MemberType noteProperty -name Datastores -value $($vm.datastore.count)
    Add-Member -Inputobject $reportedvm -MemberType noteProperty -name Datastore -value $((get-view $vm.datastore).name)
    $networkcards =$vm.guest.net
    Add-Member -Inputobject $reportedvm -MemberType noteProperty -name Nics -value $($networkcards.count)
    Add-Member -Inputobject $reportedvm -MemberType noteProperty -name Disks -value $($vm.guest.disk.count)    
    
  $reportedvms.add($reportedvm) |Out-Null
}
 
$reportedvms|Export-Csv $outfile

Disconnect-VIServer * -Confirm:$False

7/05/2013

vmware customization: sysprep issues

sysprep /generalize /reboot /oobe c:\windows\system32\sysprep\panther\setuperr.log "SYSPRP WinMain:Hit failure while processing sysprep cleanup external providers; hr = 0x8007001f" "SYSPRP RunExternalDlls:An error occurred while running registry sysprep DLLs, halting sysprep execution. dwRet = -1073425657" slmgr /dlv regedit: set the value of GeneralizationState under HKEY_LOCAL_MACHINE\SYSTEM\Setup\Status\SysprepStatus to 7 start > run: msdtc -uninstall start > run: msdtc –install delete any extra folders under c:\windows\system32\sysprep On SOURCE machine: Set the following to 1: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\SoftwareProtectionPlatform\SkipRearm **be sure the administrator user does NOT have "user cannot changed password" checked.

7/03/2013

Powershell: Compellent SAN configuration

Add Servers, Create boot volumes, map volumes to servers. Requires the right version of Compellent Storage Center and the Compellent plugin for Powershell

$user = Read-Host "userid"
$pw = Read-Host "Enter Password for $user" -AsSecureString
$san1 = get-scconnection -HostName san1 -User $user -Password $pw
$san2 = get-scconnection -HostName san2 -User $user -Password $pw
#$pass ='' #erase plain txt pw
#remove-scserver -connection $san1 $server

$inputfile = ".\test.csv"
$profiles = get-content $inputfile

foreach ($line in $profiles) {
$line
 $line = ($line -split',')
 $profile = $line[0]
 $wwn1 = $line[1]
 $wwn2 = $line[2]
 
 #Create Server
 $s1server = new-scserver -connection $san1 -name $profile
 $s2server = new-scserver -connection $san2 -name $profile

 #Set WWNs
 add-scserverport -connection $san1 -scserver $s1server -worldwidenames $wwn1
 add-scserverport -connection $san1 -scserver $s1server -worldwidenames $wwn2
 add-scserverport -connection $san2 -scserver $s2server -worldwidenames $wwn1
 add-scserverport -connection $san2 -scserver $s2server -worldwidenames $wwn2
 #Set Server OS Type 
 $s1ostype = get-SCOSType -index 35 -connection $san1
 $s1server = get-SCServer -connection $san1 -name $profile
 $s2ostype = get-SCOSType -index 35 -connection $san2
 $s2server = get-SCServer -connection $san2 -name $profile
 set-scserver $s1server -connection $san1 -SCOSType $s1ostype
 set-scserver $s2server -connection $san2 -SCOSType $s2ostype

 #Create Boot LUN
 #use "Boot LUNs" storage profile
 $storageprofile = get-scstorageprofile -connection $san2 -name "Boot LUNs"
 $volname = $profile+"_boot"
 $folder = get-scvolumefolder -connection $san2 -name "BOOT LUNS"
 $volume = new-scvolume -connection $san2 -name $volname -parentfolder $folder -scstorageprofile $storageprofile -size 10g
 #map volume
 $map = new-scvolumemap -scvolume $volume -scserver $s2server -connection $san2
}#end foreach profile
Remove-SCConnection $san1
Remove-SCConnection $san2

List HBA WWPNs and LUNs using Powershell | Arnim van Lieshout

List HBA WWPNs and LUNs using Powershell | Arnim van Lieshout: List HBA WWPNs and LUNs using Powershell

Powershell: VMWare Automation

Kick-Start Your VMware Automation with PowerCLI
https://www.simple-talk.com/sysadmin/virtualization/10-steps-to-kick-start-your-vmware-automation-with-powercli/

vCheck (Daily Report) | Virtu-Al.Net

vCheck (Daily Report) | Virtu-Al.Net: vCheck (Daily Report)
VMware powershell resources

7/02/2013

Powershell: Cisco MDS Fibre Channel Switch Zone Configuration Builder

Create Commands to configure zones on Cisco MDS 91xx switch


####################################################################################################
#
#  fc-cfg-bldr.ps1
#
#  Create cmd file for Cisco MDS fibre channel switch to create zones for new servers
#  INPUT:  CSV file containing list of server names and WWN's.
#  OUTPUT:  2 TXT files containing commands to create zones in Fabric A and Fabric B.
#

$inputfile = ".\test.csv"
#$inputfile = ".\servers.csv"
$outfile = ".\fc-cmds.txt"
$tempA = ".\\configA.txt"
$tempB = ".\\configB.txt"

$profiles = get-content $inputfile

$today = get-date
$day = $today.Day
$mth = $today.Month
$year = $today.Year
$hour = $today.Hour
$min = $today.Minute
$sec = $today.Second
$date = "$year-$mth-$day-$hour$min$sec"

clear-host

"------------------------------------------------------------------------------"
write "! $date Fabric A Configuration" | out-file $tempA -encoding ascii
write "! $date Fabric B Configuration" | out-file $tempB -encoding ascii

$zonesetA = @"
    zoneset name SAN1-SAN2-FAB-A vsan 2
"@
$zonesetB = @"
    zoneset name SAN1-SAN2-FAB-B vsan 3
"@

foreach ($profile in $profiles) {
    "!------------------------------------------------------------------------------" | out-file $tempA -encoding ascii -append
    "!------------------------------------------------------------------------------" | out-file $tempB -encoding ascii -append
    $profile
    $server = ($profile -split',')
    $name = $server[0]
    "    $name"    
    $wwn1 = $server[1]
    "    $wwn1"
    $wwn2 = $server[2]
    "    $wwn2"
    
    $zoneA1 = $name+"_hba_A_to_cmp1"
    $zoneA2 = $name+"_hba_A_to_cmp2"
    $zoneB1 = $name+"_hba_B_to_cmp1"
    $zoneB2 = $name+"_hba_B_to_cmp2"
      
    #create commands
    "    Generate Commands"


    #Create Zones in Fabric A
    "        Fab A Zones"
    $configA = @"
    zone name $zoneA1 vsan 2
        member pwwn 50:00:d3:10:00:0c:80:03
        member pwwn 50:00:d3:10:00:0c:80:09
        member pwwn 50:00:d3:10:00:0c:80:11
        member pwwn 50:00:d3:10:00:0c:80:17
        member pwwn $wwn1
    
    zone name $zoneA2 vsan 2
        member pwwn 50:00:d3:10:00:0c:82:03
        member pwwn 50:00:d3:10:00:0c:82:0b
        member pwwn 50:00:d3:10:00:0c:82:13
        member pwwn 50:00:d3:10:00:0c:82:1b
        member pwwn $wwn1
"@
    write $configA | out-file $tempA -encoding ascii -append
    
    #Add to zonesetA
    "        Add to ZonesetA"
    $configA = @"
    
        member $zoneA1    
        member $zoneA2
"@
    $zonesetA = $zonesetA + $configA
    
    #Create Zones in Fabric B
    "        Fab B Zones"
    $configB = @"
    zone name $zoneB1 vsan 3
        member pwwn 50:00:d3:10:00:0c:80:0d
        member pwwn 50:00:d3:10:00:0c:80:05
        member pwwn 50:00:d3:10:00:0c:80:1b
        member pwwn 50:00:d3:10:00:0c:80:13
        member pwwn $wwn2
    
    zone name $zoneB2 vsan 3
        member pwwn 50:00:d3:10:00:0c:82:0f
        member pwwn 50:00:d3:10:00:0c:82:05
        member pwwn 50:00:d3:10:00:0c:82:1f
        member pwwn 50:00:d3:10:00:0c:82:15
        member pwwn $wwn2    
"@
    write $configB | out-file $tempB -encoding ascii -append
    
    #Add to zonesetB
    "        Add to ZonesetB"
    $configB = @"
    
        member $zoneB1    
        member $zoneB2
"@
    $zonesetB = $zonesetB + $configB
    "-------------------------------------------------------------------------------"
}#end foreach
    "!------------------------------------------------------------------------------" | out-file $tempA -encoding ascii -append
    "!------------------------------------------------------------------------------" | out-file $tempB -encoding ascii -append


#Config zonesets
    write $zonesetA | out-file $tempA -encoding ascii -append
    write $zonesetB | out-file $tempB -encoding ascii -append

#Activate & Save
"        Complete Configs"
    $configA = @"

        zoneset activate name SAN1-SAN2-FAB-A vsan 2
    
        zone commit vsan 2
    
        copy run start
"@
    write $configA | out-file $tempA -encoding ascii -append
    
    $configB = @"

    zoneset activate name SAN1-SAN2-FAB-B vsan 3
    
    zone commit vsan 3
    
    copy run start
"@
    write $configB | out-file $tempB -encoding ascii -append    

"-------------------------------------------------------------------------------"
"    COMPLETE - Configuration commands saved to $tempA, $tempB"
"-------------------------------------------------------------------------------"

SYSPREP on cloned Windows Server 2008 R2 Fails

Trouble with sysprep not running when vmware runs customization after deploying a Win2K8R2 template. -> SID for all the clones is the same. Supposedly this matters much less these days but some odd stuff happened that we couldn't explain when we attempted to join to AD domain (NEWSID doesn't work past Win2003) SYSPREP logs are located at: c:\windows\system32\sysprep\panther log files: setupact.log, setuperr.log Apparently sysprep will not run when it thinks Windows has been upgraded in place. This particular template they were copying had several applications installed on it for which we don't know the owner so rebuilding fresh was not an option. The following worked to allow sysprep to run: - Remove the machine from the domain - Registry export: HKLM\SYSTEM\Setup (as backup) - Delete from the registry: HKLM\SYSTEM\Setup\Upgrade - Run: c:\windows\system32\Sysprep\Sysprep.exe /oobe /generalize

7/01/2013

Cloning Windows Server 2008 R2: Use Sysprep (no more NewSID) - Ray Heffer

Cloning Windows Server 2008 R2: Use Sysprep (no more NewSID) - Ray Heffer: Cloning Windows Server 2008 R2: Use Sysprep (no more NewSID)

VMware KB: Cannot run Sysprep on a Windows virtual machine that was upgraded to a later version

VMware KB: Cannot run Sysprep on a Windows virtual machine that was upgraded to a later version: Cannot run Sysprep on a Windows virtual machine that was upgraded

Howto: Build a Windows Server 2008 R2 VMware Template | Mike's Realm

Howto: Build a Windows Server 2008 R2 VMware Template | Mike's Realm: Windows Server 2008 R2 VM Template

Powershell: Bulk Creation of HP-BL Virtual Connect Profiles

Powershell: Bulk Creation of HP-BL Virtual Connect Profiles


####################################################################################################
#
#  clone-profile.ps1
#
#  Copy a template and associate with physical server
#  INPUT:  CSV file containing list of profile names, IP# of enclosure, and Bay
#

$vcuser = "admin"
$inputfile = ".\servers.csv"


$pw = Read-Host "Enter Password for $vcuser" -AsSecureString
$profiles = get-content $inputfile
$tempfile = ".\\cmdfile.txt"

$today = get-date
$day = $today.Day
$mth = $today.Month
$year = $today.Year
$hour = $today.Hour
$min = $today.Minute
$sec = $today.Second
$date = "$year-$mth-$day-$hour$min$sec"
$logfile = ".\create-profile-$date.log"

write "$date Create HP BL Profiles" | out-file $logfile -encoding ascii
clear-host
foreach ($profile in $profiles) {
	"--------------------------------------------------------------------------------" | out-file $logfile -encoding ascii -append
	$profile
	$profile | out-file $logfile -encoding ascii -append
	$server = ($profile -split',')
	$name = $server[0]
	$vcip = $server[1]
	$bay = $server[2]
	if ($vcip -eq "10.2.9.147") { $template = "Template01" }
	if ($vcip -eq "10.2.9.177") { $template = "Template_2" }

	#create command file
	write "copy profile $template $name" | out-file $tempfile -encoding ascii
        write "poweroff server $bay -force" | out-file $tempfile -encoding ascii -append
        write "assign profile $name $bay" | out-file $tempfile -encoding ascii -append	

	#convert $pw to plain text
		$pass = [Runtime.InteropServices.Marshal]::PtrToStringAuto(
			[Runtime.InteropServices.Marshal]::SecureStringToBSTR($pw))
	$result = (./plink.exe -batch -ssh -l $vcuser -pw $pass $vcip -m $tempfile) | out-string
	$pass ='' #erase plain txt pw
	$result
	$result | out-file $logfile -encoding ascii -append
}#end foreach
"--------------------------------------------------------------------------------" | out-file $logfile -encoding ascii -append