Help Creating a Function To Find Servers
I have a multi-domain environment and would like to create a function that will find servers by the domain in which they reside and the role they host. This will be used in a number of scripts, so I would like to make it a function. E.G. find all servers in the "NA.company.com" domain running the "mailbox" role. I would also like to make it user friendly so that if you type "US", "USA", "NA", "eu", etc., it will convert to "NA.domain.com" or "europe.domain.com" appropriately; and, if you do not enter a value, it defaults to the NA domain. Here is what I have so far, but it does not seem to work properly: Function FindServers ($Domain,$Role){ if ($Domain -eq 'na.domain.com' -or 'europe.domain.com') {} else { switch ($Domain){ $null { $Domain = 'na.domain.com' } 'US' { $Domain = 'na.domain.com' } 'USA'{ $Domain = 'na.domain.com' } 'America'{ $Domain = 'na.domain.com' } 'NA' { $Domain = 'na.domain.com' } 'EU' { $Domain = 'europe.domain.com' } default { throw 'Please enter a valid domain name such as "na" or "europe".' } } } Get-ExchangeServer | where { $_.fqdn -like '"*' + $Domain -and $_.serverrole -like '"*' + $role + '*"' }} The "switch" statement by itself works properly, converting "us" to "na.domain.com" for example. However, when I try it inside the "if" statement it does not. I would like it to skip the switch statement if the $domain variable evaluates to a proper fqdn such as "na.domain.com", however it seems the switch statement does not run at all, regardless of the value of $domain. Am I on the right track or is there a much better way to do this? BTW: the reason i am trying to key on the FQDN is that I could not find another property to distinguish between servers in different domains. Is there a better/easier way? Thanks, Dan
April 7th, 2010 6:53pm

Try this: if ($Domain -eq 'na.domain.com' -or $Domain -eq 'europe.domain.com') In the if statement, either side of the -or is a separate espression, being used as a boolean test. 'equrope.domain.com' by itself is a valid string expression, and any non-null string will always evaluate as $true when used as a boolean, so your if is always going to be true, and your switch will never run.
Free Windows Admin Tool Kit Click here and download it now
April 7th, 2010 7:03pm

That was it, thanks mjolinor. After a few more tweaks, here is the working function: Function FindServers ($Domain,$Role){$AdminSessionADSettings.ViewEntireForest = $True if ($Domain -ne ('na.domain.com' -or 'europe.domain.com')) { switch ($Domain) { $null { $Domain = 'na.domain.com' } 'US' { $Domain = 'na.domain.com' } 'USA'{ $Domain = 'na.domain.com' } 'America'{ $Domain = 'na.domain.com' } 'NA' { $Domain = 'na.domain.com' } 'EU' { $Domain = 'europe.domain.com' } default { throw 'Please enter a valid domain name such as "ad" or "europe".'} } }Get-ExchangeServer | where { $_.fqdn -match $Domain -and $_.serverrole -match $role }}
April 7th, 2010 9:22pm

On Wed, 7 Apr 2010 18:22:49 +0000, Dan DeStefano wrote:>That was it, thanks mjolinor. >>After a few more tweaks, here is the working function: >>Function FindServers ($Domain,$Role){$AdminSessionADSettings.ViewEntireForest = $True if ($Domain -ne ('na.domain.com' -or 'europe.domain.com')) { switch ($Domain) { $null { $Domain = 'na.domain.com' } 'US' { $Domain = 'na.domain.com' } 'USA'{ $Domain = 'na.domain.com' } 'America'{ $Domain = 'na.domain.com' } 'NA' { $Domain = 'na.domain.com' } 'EU' { $Domain = 'europe.domain.com' } default { throw 'Please enter a valid domain name such as "ad" or "europe".'} } }Get-ExchangeServer | where { $_.fqdn -match $Domain -and $_.serverrole -match $role }} I don't think it's working the way you think it is.This evaluates to $true -- ALWAYS: ('a' -or 'b')This, for example, should evaluate to $true if you want to execute theswitch statement: $d = 'a' $d -ne ('a' -or 'b')But no matter what value you set $d to, the test is going to return$true.That statement should be: ($d -ne 'a' -and $d -ne 'b')Now the switch will be evaluated only when $d isn't one of the valuesyou're looking for.Combining "not equal" together with "and" and "or" conditions has beenthe bane of programmers since I started writing code in 1964.A less ambiguous way to write the conditional statement might be likethis: if ('a','b' -notcontains $d)where 'a' and 'b' are the two domain names, and $d is the variableholding the value to be evaluated.Maybe even a better way is to eliminate the conditional statementcompletely and just add 'a' and 'b' as part of the switch statementand just provide an empty expression for each of them.---Rich MatheisenMCSE+I, Exchange MVP--- Rich Matheisen MCSE+I, Exchange MVP
Free Windows Admin Tool Kit Click here and download it now
April 8th, 2010 2:56am

Well, you are right. It worked as long as I manually populated the value for $Domain. However, if I ran the 'if' statement to set the domain name, then ran it again, I always got the error. I also tried changing it to ($d -ne 'a' -and $d -ne 'b'), with the same results. I do not know why this is and would appreciate if you can help me understand, out of curiosity. I modified the function as you suggested (at least, I think I have), removing the "if" statement, but it still does not work completely right: Function FindServers ($Domain,$Role){ # Evaluate the '$Domain' parameter and correct if necessary switch ($Domain){'na.domain.com' {}'US' { $Domain = 'na.domain.com' }'USA'{ $Domain = 'na.domain.com' }'America'{ $Domain = 'na.domain.com' }'NA' { $Domain = 'na.domain.com' }$null { $Domain = 'na.domain.com' }'europe.domain.com' {}'EU' { $Domain = 'europe.domain.com' }'Europe' { $Domain = 'europe.domain.com' }default { throw 'Please enter a valid domain name such as "na" or "europe".'}} # Find all servers where the "fqdn" property matches the value of the "$Domain" parameter`# and the "ServerRole" property matches the "$Role" parameter. Get-ExchangeServer | where { $_.fqdn -match $Domain -and $_.serverrole -match $role }} I would expect this to work as follows: if the value for $Domain is anything in the switch statement, then set it to the corresponding value, if it is anything else, then throw the error message. The first part works correctly - if I set $Domain to any of the values in the switch statement (including $null), it is modified properly. However, if I set it to an invalid value such as 'dlfkdjfj', it still sets it to 'na.domain.com' and it executes successfully. I thought that if none of the values match that the default expression is supposed to execute? Am I not understanding how the switch statment works? Additionally, if I check the value of the $Domain variable after running the above code, it says 'dlfkdjfj', instead of 'na.domain.com', but it gave the proper results for the get-exchangeserver pipeline. Does the code reset the variable value after it finishes executing? Thanks for your patience as I am quite novice to scripting. Dan
April 8th, 2010 10:09pm

From get-help about_switch By default, if no parameters are used, Switch behaves as if a case- insensitive exact match is in effect. If "pipeline" results in an array, each element of the array will be evaluated in ascending offset order (starting at 0 [zero]). At least one conditional element must be present in the Switch codeblock, and only one default clause can be present. If more than one default clause is present, a ParseException will be thrown. Switch has the following parameters: Regex Indicates that the match clause, if it is a string, is treated as a regex string. Use of this parameter disables Wildcard and Exact. If the match clause is not a string, this parameter is ignored. Wildcard Indicates that the match clause, if it is a string, is treated as a wildcard string. Use of this parameter disables Regex and Exact. If the match clause is not a string, this parameter is ignored. Exact Indicates that the match clause, if it is a string, must match exactly. Use of this parameter disables Wildcard and Regex. If the match clause is not a string, this parameter is ignored. CaseSensitive Modifies the match clause, if it is a string, to be case-sensitive. If the match clause is not a string, this parameter is ignored. File Takes input from a file (or representative) rather than a statement. If multiple File parameters are used, the last one is used. Each line of the file is read and passed through the switch block. What you have there looks like it would probably work as you expect using the -regex switch, with the exception of the $null. There is some potential for unintended consequences. if a domain name contained both "us" and "eu" anywhere in the name, it's going to match more than one switch clause, and every swith block with a matching clause will get ran.
Free Windows Admin Tool Kit Click here and download it now
April 9th, 2010 1:14am

On Thu, 8 Apr 2010 19:09:35 +0000, Dan DeStefano wrote: [ snip ]>I modified the function as you suggested (at least, I think I have), removing the "if" statement, but it still does not work completely right: >> Function FindServers ($Domain,$Role){ >># Evaluate the '$Domain' parameter and correct if necessary switch ($Domain){'na.domain.com' {}'US' { $Domain = 'na.domain.com' }'USA'{ $Domain = 'na.domain.com' }'America'{ $Domain = 'na.domain.com' }'NA' { $Domain = 'na.domain.com' }$null { $Domain = 'na.domain.com' }'europe.domain.com' {}'EU' { $Domain = 'europe.domain.com' }'Europe' { $Domain = 'europe.domain.com' }default { throw 'Please enter a valid domain name such as "na" or "europe".'}} >># Find all servers where the "fqdn" property matches the value of the "$Domain" parameter`# and the "ServerRole" property matches the "$Role" parameter. Get-ExchangeServer | where { $_.fqdn -match $Domain -and $_.serverrole -match $role }} >>I would expect this to work as follows: if the value for $Domain is anything in the switch statement, then set it to the corresponding value, if it is anything else, then throw the error message. The first part works correctly - if I set $Domain to any of the values in the switch statement (including $null), it is modified properly. However, if I set it to an invalid value such as 'dlfkdjfj', it still sets it to 'na.domain.com' and it executes successfully. I thought that if none of the values match that the default expression is supposed to execute? Am I not understanding how the switch statment works? Additionally, if I check the value of the $Domain variable after running the above code, it says 'dlfkdjfj', instead of 'na.domain.com', but it gave the proper results for the get-exchangeserver pipeline. Does the code reset the variable value after it finishes executing? >>Thanks for your patience as I am quite novice to scripting. See it this helps (a couple of the lines may be wrapped):###########################$NA = 'na.domain.com'$EU = 'europe.domain.com''na.domain.com','us','usa','america','na',$null,'europe.domain.com','eu','europe','bogus.local'| foreach { $Domain = $_ $Domain1 = $null switch -exact ($Domain) { 'na.domain.com' { $Domain1 = $NA; break } 'US' { $Domain1 = $NA; break } 'USA' { $Domain1 = $NA; break } 'America' { $Domain1 = $NA; break } 'NA' { $Domain1 = $NA; break } $null { $Domain1 = $NA; break } 'europe.domain.com' { $Domain1 = $EU; break } 'EU' { $Domain1 = $EU; break } 'Europe' { $Domain1 = $EU; break } default { throw 'Please enter a valid domain name suchas "na" or "europe".'} } Write-host "IN := '$domain' ; OUT := '$domain1'"}###########################When you're trying to debug code, using the same variable for theinput and output makes it a bit hard to figure out where things aregoing wrong. In the example I used $domain as the input and $domain1as the output.Your switch statment will work okay, but it holds a potential sourceof future bugs. I added the "-exact" option so a match isn'tunintentional. While that's the default, I prefer to explicitly statewhat I mean. I also added a "break" to each code block so one, andonly one, expression will be matched if you later change the "-exact"to, say, "-regex" or "-wildcard".I also replaced the repetitive strings with variables.Running the whole code snippet will excercise each switch expression.You won't be able to test more than one error condition, though."Throw"ing an error terminates the block.---Rich MatheisenMCSE+I, Exchange MVP--- Rich Matheisen MCSE+I, Exchange MVP
April 9th, 2010 7:01am

Rich, I tried your suggestion, but could not get it to work the way I needed. The $Domain1 variable always evaluated to "Europe". So, I tried simply adding the "-exact" parameter to the "switch" statement, then adding ";break" to the end of each clause. This worked exactly as I need. It sets the domain name properly and also throws the error message when the $Domain variable is not set to one of the clauses. Thanks for all of your help, Rich and mjolinor. Dan
Free Windows Admin Tool Kit Click here and download it now
April 9th, 2010 4:34pm

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics