Monday, May 1, 2017

Wfa command to set SPN

This command allows you set a service principal name (SPN).  I needed this command a few years back to handle SVM-DR (Cdot 8.2).  In my case, cifs clients would work against a dns-alias, during the cutover, the dns-alias would flip from the old svm-name to the new svm-name.  Even if the DNS-flip is instantaneous to client (TTL 0, dns cache cleared, etc...), during a snapmirror-break-dr-activate from one CIFS-SVM to another CIFS-SVM, you have a kerberos issue.  Your cifs clients still have the old kerberos ticket and won't trust the new connection to the new SVM (different name).  That's why you need to unregister the old svm name and register the new instead.  (in a snapmirror relation, the svm-names must be different).


Here is the code

param(
[parameter(mandatory=$true,helpmessage='Old Vserver name - to get unregistered')]
[string]$vserverOld,

[parameter(mandatory=$true,helpmessage='New Vserver name - to get registered')]
[string]$vserverNew,

[parameter(mandatory=$true,helpmessage='The Cifs alias, the name of the cifs server')]
[string]$alias,

[parameter(mandatory=$true,helpmessage='domain name')]
[string]$domainname
)

# set to lowercase
$vserverOld=$vserverOld.ToUpper()
$vserverNew=$vserverNew.ToUpper()
$domainname=$domainname.ToLower()

# function - will run a cmd with or without output
function runCmd($cmd,[switch]$showoutput){
    Get-WfaLogger -info -message  "--> cmd [$cmd]"
    $expression = "cmd.exe /C `"$cmd 2>&1`""
    Get-WfaLogger -info -message  "--> Invoke-Expression -Command $expression"

    try{
        $null = Invoke-Expression -Command $expression -ErrorAction Stop 2>$null -OutVariable Out
        if($LASTEXITCODE){
            throw "Failed to run $cmd"
        }else{
            if($showoutput){
                $Out
            }
        }
    }catch{
        Get-WfaLogger -warn -message  $_.Exception.Message
    }
    $Error.Clear()
}

Get-WfaLogger -info -message  "Swapping spn for [$alias] from [$vserverOld] -> [$vserverNew]"

# remove the old spn
runCmd "setspn -D HOST/$alias $vserverOld"
runCmd "setspn -D HOST/$alias.$domainname $vserverOld"

# add the new spn
runCmd "setspn -A HOST/$alias $vserverNew"
runCmd "setspn -A HOST/$alias.$domainname $vserverNew"

# get current spn
$current = runCmd "setspn -L $alias.$domainname" -showoutput

# parse the current spn
foreach($c in $current){
 # search for spn host entries 
 if(([string]$c).ToLower() -match "^\shost/(.*)"){
  [string]$spn = $Matches[1]
  [string]$validspns = ""
  $validspns+="$alias"
  $validspns+="|$alias.$domainname"
  $validspns+="|$vserverNew"
  $validspns+="|$vserverNew.$domainname"
 $validspns=$validspns.toUpper()
 $spn=$spn.toUpper()
  switch -Regex ($spn) {
   ("^\b($validspns)\b$"){
    Get-WfaLogger -info -message  "$_ [OK]"
   }
   default{
    Get-WfaLogger -warn -message  "$_ is not an expected spn"
   }
  }
 }
}


$Error




No comments :

Post a Comment