Need help with PowerShell and determining if a value is present in the msDS-AllowedToDelegateTo attribute of a computer object.

Folks -

I have a PowerShell script that adds values to the msDS-AllowedToDelegateTo attribute of various computer objects in my environment for Kerberos Constrained Delegation.  I'm finding that running this script regularly is clogging my audit logs and therefore, I'd like to modify it so that it only adds values if they are NOT present in the attribute already.

The small function that performs the value addition is as follows.  It adds the KCD entries with the NetBIOS and FQDN's of $Host1 to the computer $Host2.

Function ConfigureVMHostKCD($Host1, $Host2)
{
	$Host1Name = $Host1.Name
	$Host1FQDN = $Host1.Name + ".mydomain.lcl"

	Get-ADComputer $Host2 | Set-ADObject -Add @{"msDS-AllowedToDelegateTo"="Microsoft Virtual System Migration Service/$Host1FQDN", "Microsoft Virtual System Migration Service/$Host1Name", "cifs/$Host1FQDN", "cifs/$Host1Name"}
}

Open in new window


Essentially, this adds the KCD entries required for Hyper-V Live Migration technologies.  What I'd like to do is modify the function to wrap a conditional in there somehow.  I'd only like to commit the write if any of the four delegation values are NOT present.  The four values are listed above but for clarity, they are as follows (where the strings are obvious substitutes):

1. Microsoft Virtual System Migration Service/$Host1FQDN
2. Microsoft Virtual System Migration Service/$Host1Name
3. cifs/$Host1FQDN
4. cifs/$Host1Name

I'm having a problem structuring my 'if' statement though.  What I need is for the Get-ADComputer statement to execute only if one of the four values that it would have added is missing from the attribute msDS-AllowedToDelegateTo on the computer account of $Host2.

Any input is appreciated.

Thank you.
amendalaAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Will SzymkowskiSenior Solution ArchitectCommented:
Below is a Try/Catch statment for this function. Give that a shot.
Function ConfigureVMHostKCD($Host1, $Host2)
{

    $Host1Name = $Host1.Name
	$Host1FQDN = $Host1.Name + ".mydomain.lcl"

      Try {

	    Get-ADComputer -filter { msDS-AllowedToDelegateTo -eq $null } -ErrorAction stop

    } catch { 

        Set-ADObject -Add @{"msDS-AllowedToDelegateTo"="Microsoft Virtual System Migration Service/$Host1FQDN", "Microsoft Virtual System Migration Service/$Host1Name", "cifs/$Host1FQDN", "cifs/$Host1Name"}

   }

}

Open in new window


Will.
amendalaAuthor Commented:
Will -

Wouldn't that only trigger the write if all the values are NOT present rather than any of the four?  That's not what I'm looking for.

What I want is a conditional test to verify that *each* of the four values that would have been written by the Set-ADComputer statement are present and if not, to write them.  Your solution would only write the values if the entire attribute was empty, which will almost never be the case in my environment.

The 'if' block is what I'm having trouble with since I find working with arrays/lists in PowerShell quite frustrating.  The msDS-AllowedToDelegateTo attribute is a multi-value attribute.

Thanks,
Andy
NinjaStyle82Systems AdministratorCommented:
I think just use -replace instead of -add to get them all squared away.
Determine the Perfect Price for Your IT Services

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden with our free interactive tool and use it to determine the right price for your IT services. Download your free eBook now!

amendalaAuthor Commented:
That would flush the entire attribute and replace it with a new list.  That would break anything else that has configured KCD entries on the computer account which would break other applications.  So "-add" must be the action.
Will SzymkowskiSenior Solution ArchitectCommented:
Ahhh, ok I will post back shortly if added If statements.

Will.
NinjaStyle82Systems AdministratorCommented:
I get it now. :)
oBdACommented:
The following script should do the trick.
I took the liberty of renaming both the function and the arguments.
Function names ideally should follow the cmdlet convention of <verb>-<noun>, with the verb being one of the "approved" ones (use Get-Verb, see http://msdn.microsoft.com/en-us/library/ms714428.aspx as well).
Since PS supports named arguments, the argument names should be somewhat self-descriptive. Nobody except you knows what "Host1" and "Host2" stands for, and it doesn't help that both are named nearly identical, while one expects an object with a property "Name", and the other a plain string.
That said. here's the script; it supports "-Verbose" as well if you want to see what it's doing.
Function Set-VMHostKCD {
[CmdletBinding()]
Param(
	$DelegateTo,
	$ComputerName
)
	$DelegateToName = $DelegateTo.Name
	$DelegateToFQDN = $DelegateTo.Name + ".mydomain.lcl"
	$KCDList = @(
		"Microsoft Virtual System Migration Service/$($DelegateToFQDN)"
		"Microsoft Virtual System Migration Service/$($DelegateToName)"
		"cifs/$($DelegateToFQDN)"
		"cifs/$($DelegateToName)"
	)
	$ADComputer = Get-ADComputer -Identity $ComputerName -Property "msDS-AllowedToDelegateTo"
	If ($ADComputer."msDS-AllowedToDelegateTo") {
		"Attribute 'msDS-AllowedToDelegateTo' is already set:" | Write-Verbose
		$ADComputer."msDS-AllowedToDelegateTo" | Sort-Object | % {"  * $($_)"} | Write-Verbose
		$KCDListMissing = @()
		$KCDList | % {
			If ($ADComputer."msDS-AllowedToDelegateTo" -notcontains $_) {
				$KCDListMissing += $_
			}
		}
		If ($KCDListMissing) {
			"Missing entries found, will add the following entries:" | Write-Verbose
			$KCDListMissing | Sort-Object | % {"  * $($_)"} | Write-Verbose
			[string[]]$KCDListMerged = ($KCDListMissing + $ADComputer."msDS-AllowedToDelegateTo") | Sort-Object
			$ADComputer | Set-ADComputer -Replace @{"msDS-AllowedToDelegateTo" = $KCDListMerged}
		} Else {
			"All required entries in attribute 'msDS-AllowedToDelegateTo' found." | Write-Verbose
		}
	} Else {
		"Attribute 'msDS-AllowedToDelegateTo' not set, will add the following entries:" | Write-Verbose
		$KCDList | % {"  * $($_)"} | Write-Verbose
		$ADComputer | Set-ADComputer -Add @{"msDS-AllowedToDelegateTo" = $KCDList}
	}
}

Open in new window

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
amendalaAuthor Commented:
obda - Your solution might work, I didn't have a chance to test it.  I ended up coming up with my own solution yesterday but didn't have time to post it here until now.  It's quite simple and readable.  The challenge I had was in working with the lists, the nomenclature and syntax drive me crazy.

Simply adding "-ExpandProperty" to the "Select" statement allowed me to leverage traditional logic (e.g. -notcontains, -eq, etc.) in simple IF statements.

Thus:

Function ConfigureVMHostKCD($Host1, $Host2)
{
	$Host1Name = $Host1.Name
	$Host1FQDN = $Host1.Name + ".mydomain.lcl"

	$targetDelegationList = Get-ADComputer $Host2 -Properties * | Select -ExpandProperty msDS-AllowedToDelegateTo
	
	# Delegation for SCVMM service w/FQDN.
	if ($targetDelegationList -notcontains "Microsoft Virtual System Migration Service/$Host1FQDN")
	{
		Get-ADComputer $Host2 | Set-ADObject -Add @{"msDS-AllowedToDelegateTo"="Microsoft Virtual System Migration Service/$Host1FQDN"}
	}
	
	# Delegation for SCVMM service w/NetBIOS name.
	if ($targetDelegationList -notcontains "Microsoft Virtual System Migration Service/$Host1Name")
	{
		Get-ADComputer $Host2 | Set-ADObject -Add @{"msDS-AllowedToDelegateTo"="Microsoft Virtual System Migration Service/$Host1Name"}
	}

	# Delegation for CIFS service w/FQDN.
	if ($targetDelegationList -notcontains "cifs/$Host1FQDN")
	{
		Get-ADComputer $Host2 | Set-ADObject -Add @{"msDS-AllowedToDelegateTo"="cifs/$Host1FQDN"}
	}

	# Delegation for CIFS service w/NetBIOS name.
	if ($targetDelegationList -notcontains "cifs/$Host1Name")
	{
		Get-ADComputer $Host2 | Set-ADObject -Add @{"msDS-AllowedToDelegateTo"="cifs/$Host1Name"}
	}
}

Open in new window


Thank you all for your input, much appreciated.
amendalaAuthor Commented:
Because I developed it.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Powershell

From novice to tech pro — start learning today.