Summary: Microsoft Scripting Guy, Ed Wilson, talks about using the Windows PowerShell Contains operator to work with arrays.
Microsoft Scripting Guy, Ed Wilson, is here. Today I am happy to provide you with an excerpt from my book Windows PowerShell 3.0 Step by Step, published by Microsoft Press.
Examine contents of an array
To verify input that is received from the command line, you can use the Contains operator to examine the contents of an array of possible values. This following technique illustrates an array of three values that is created and stored in the variable $noun. The Contains operator is then used to see if the array contains "hairy-nosed wombat". Because the $noun variable does not have an array element that is equal to the string "hairy-nosed wombat," the Contains operator returns False.
PS C:\> $noun = "cat","dog","rabbit"
PS C:\> $noun -contains "hairy-nosed wombat"
False
PS C:\>
If an array contains a match, the Contains operator returns True, as shown here:
PS C:\> $noun = "cat","dog","rabbit"
PS C:\> $noun -contains "rabbit"
True
PS C:\>
The Contains operator returns True only when there is an exact match. Partial matches return False. This is shown here:
PS C:\> $noun = "cat","dog","rabbit"
PS C:\> $noun -contains "bit"
False
PS C:\>
The Contains operator is case insensitive. Therefore, it will return True when matched, regardless of case:
PS C:\> $noun = "cat","dog","rabbit"
PS C:\> $noun -contains "Rabbit"
True
PS C:\>
If you need to perform a case sensitive match, you can use the case sensitive version of the Contains operator, -ccontains. As shown here, it will return True only if the case of the string matches the value that is contained in the array:
PS C:\> $noun = "cat","dog","rabbit"
PS C:\> $noun -ccontains "Rabbit"
False
PS C:\> $noun -ccontains "rabbit"
True
PS C:\>
In the Get-AllowedComputers.ps1 script, a single command-line parameter is created, which is used to hold the name of the target computer for the WMI query. The computer parameter is a string, and it receives the default value from the environmental drive. This is a good technique because it ensures that the script will have the name of the local computer, which could then be used to produce a report of the results. If you set the value of the computer parameter to LocalHost, you never know what computer the results belong to. This is shown here:
Param([string]$computer = $env:computername)
The Get-AllowedComputer function is used to create an array of permitted computer names and to check the value of the $computer variable to see if it is present. If the value of the $computer variable is present in the array, the Get-AllowedComputer function returns True. If the value is missing from the array, the Get-AllowedComputer function returns False.
The array of computer names is created by using the Get-Content cmdlet to read a text file that contains a list of computer names. The text file, servers.txt, is a plain ASCII text file that has a list of computer names on individual lines, as shown in the following image:
A text file of computer names is easier to maintain than a hard-coded array that is embedded into the script. In addition, the text file can be placed on in central shared folder, and it can be used by many different scripts. The Get-AllowedComputer function is shown here:
Function Get-AllowedComputer([string]$computer)
{
$servers = Get-Content -path c:\fso\servers.txt
$servers -contains $computer
} #end Get-AllowedComputer function
Because the Get-AllowedComputer function returns a Boolean value (True/False) it can be used directly in an IF statement to determine if the value that is supplied for the $computer variable is on the permitted list. If the Get-AllowedComputer function returns True, the Get-WmiObject cmdlet is used to query for BIOS information from the target computer. This is shown here:
if(Get-AllowedComputer -computer $computer)
{
Get-WmiObject -class Win32_Bios -Computer $computer
}
On the other hand, if the value of the $computer variable is not found in the $servers array, a string that states the computer is not an allowed computer is displayed:
Else
{
"$computer is not an allowed computer"
}
Following is the complete Get-AllowedComputer.ps1 script:
Get-AllowedComputer.ps1
Param([string]$computer = $env:computername)
Function Get-AllowedComputer([string]$computer)
{
$servers = Get-Content -path c:\fso\servers.txt
$servers -contains $computer
} #end Get-AllowedComputer function
# *** Entry point to Script ***
if(Get-AllowedComputer -computer $computer)
{
Get-WmiObject -class Win32_Bios -Computer $computer
}
Else
{
"$computer is not an allowed computer"
}
Test for properties
You are not limited to only testing for specified computer names in the Get-AllowedComputer function. All you need to do is add additional information to the text file, as shown in the following image:
A couple of modifications to the Get-AllowedComputer.ps1 script are all that is required to turn it into the Get-AllowedComputerAndProperty.ps1 script. The first is to add an additional command line parameter to allow the user to choose which property to display:
Param([string]$computer = $env:computername,[string]$property="name")
Next, the signature to the Get-AllowedComputer function is changed to permit passing the Property name. Instead of directly returning the results of the Contains operator, the returned values are stored in variables. The Get-AllowedComputer function first checks to see if the $servers array contains the computer name. It then checks to see if the $servers array contains the Property name. Each of the resulting values is stored in variables. The two variables are then added together, and the result returns to the calling code. When two Boolean values are added together, only the “True and True” case is equal to True. This is shown here:
PS C:\> $true -and $false
False
PS C:\> $true -and $true
True
PS C:\> $false -and $false
False
PS C:\>
Following is the revised Get-AllowedComputer function:
Function Get-AllowedComputer([string]$computer, [string]$property)
{
$servers = Get-Content -path c:\fso\serversAndProperties.txt
$s = $servers -contains $computer
$p = $servers -contains $property
Return $s -and $p
} #end Get-AllowedComputer function
The if statement is used to determine if both the computer value and the property value are contained in the allowed list of servers and properties. If the Get-AllowedComputer function returns True, the Get-WmiObject cmdlet is used to display the chosen property value from the selected computer. This is shown here:
if(Get-AllowedComputer -computer $computer -property $property)
{
Get-WmiObject -class Win32_Bios -Computer $computer |
Select-Object -property $property
}
If the computer value and the property value are not on the permitted list, the Get-AllowedComputerAndProperty.ps1 script displays a message that states there is a non-permitted value:
Else
{
"Either $computer is not an allowed computer, `r`nor $property is not an allowed property"
}
The complete Get-AllowedComputerAndProperty.ps1 script is shown here:
Get-AllowedComputerAndProperty.ps1
Param([string]$computer = $env:computername,[string]$property="name")
Function Get-AllowedComputer([string]$computer, [string]$property)
{
$servers = Get-Content -path c:\fso\serversAndProperties.txt
$s = $servers -contains $computer
$p = $servers -contains $property
Return $s -and $p
} #end Get-AllowedComputer function
# *** Entry point to Script ***
if(Get-AllowedComputer -computer $computer -property $property)
{
Get-WmiObject -class Win32_Bios -Computer $computer |
Select-Object -property $property
}
Else
{
"Either $computer is not an allowed computer, `r`nor $property is not an allowed property"
}
Join me tomorrow when I will talk about more cool Windows PowerShell stuff.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy