Using a Variable as a Parameter - Powershell - powershell

I am trying to pass a variable through to be used as a parameter within a function. I'm not even sure if this is possible but below is what i am attempting to accomplish, what i have tried so far keeps kicking out a "positional parameter cannot be found that accepts argument" error
$Var = Read-host "enter Attribute number"
$CustomAtt = "CustomAttribute$Var"
Get-Mailbox -Identity $Email | Set-Mailbox -$CustomAtt "TestTest"

You cannot set cmdlet arguments that way in powershell. You can do what your are attempting to do by using a feature called argument splatting. Simply store your arguments in an array or hashtable and then apply them to the cmdlet using # symbol.
Like this:
$mailBoxAttributes = #{
$CustomAtt = "TestTest" }
Get-Mailbox -Identity $Email | Set-Mailbox #mailBoxAttributes

Related

How to access properties in a nested hashtable without explicitly stating the property names?

Let's say I have a 2-level nested hashtable like this:
$programs = #{
program1 = #{
DisplayName = "DisplayName1"
Program = "C:\program1.exe"
}
program2 = #{
DisplayName = "DisplayName2"
Program = "C:\program2.exe"
}
}
now, without explicitly mentioning each of the property names like this:
$programs.program1['program']
I want to iterate over the hashtable like this:
foreach ($Name in $programs) {
$r = Get-NetFirewallRule -DisplayName $programs.Keys['DisplayName'] 2> $null;
if (-NOT $r) {
New-NetFirewallRule -DisplayName $programs.Keys['DisplayName'] -Program $program.Keys['Program']
}
}
but I keep getting errors like:
Cannot validate argument on parameter 'DisplayName'. The argument is null. Provide a valid value for the argument, and then try running the command again.
InvalidOperation: untitled:Untitled-2:29:13
what am I doing wrong?
what is the right way to access nested hashtable properties like this without explicitly mentioning their names? I want to know the synatx of it so that if I ever have a 3 or 4 level nested hashtables I can access them without specifying their exact names.
even if we ignore the foreach loop, how to only list all the "DisplayName" properties? what if the "DisplayName" properties were in a 4-level nested hashtable and we wanted to list them in the PowerShell console without specifying the exact names of the items that came before it?
Thanks to the comments from Santiago Squarzon and zett42, here is the syntax to access properties of deeply nested hashtables.
$programs.Values.Values.Values and so on.
I found it work perfectly.
also, after reading foreach and as mentioned in the comments, I found that my code above was incorrect and the correct way is this:
foreach ($Name in $programs.values.GetEnumerator()) {
$r = Get-NetFirewallRule -DisplayName $Name.DisplayName 2> $null;
if (-NOT $r) {
New-NetFirewallRule -DisplayName $Name.DisplayName -Program $Name.Program
}
}
in a foreach loop, we have to use the variable we create in the parenthesis. my mistake was that I was using the collection itself again.

Set-ADuser extensionAttribute won't work but things like title will

I am writing a simple script that takes an already created user and updates an attribute based on what the admin put in.
The code works just fine if I replace extensionAttribute with for example title or something like that, but it won't with extensionAttributes.
I have tried a few things and other extensionAttributes but the code is so simple and it works with other Attributes. I am guess extensionAttributes require a bit more in the code that I am missing.
$name = Read-Host "AD Logon Name"
$key = Read-Host "Azure Key"
Set-ADUser $name -extensionAttribute6 $key -PassThru
Set-ADUser : A parameter cannot be found that matches parameter name 'extensionAttribute6'
Even though it exists it is not finding it.
Set-ADUser has a limited set of parameters covering the most commonly used attributes in AD. However, given the sheer amount of existing attributes and the fact that the AD schema is extensible, an attempt to have all attributes represented as parameters just wouldn't be feasible.
For attributes that are not represented as parameters use the parameter -Add or -Replace with a hashtable argument.
Set-ADUser $name -Replace #{'extensionAttribute6' = $key} -PassThru
Old thread, but this worked for me:
Import-Csv -Path "C:\data\12345.csv" |ForEach-Object {
Set-ADUser $_.samAccountName -replace #{
description = "$($_.description)"
extensionAttribute1 = "$($_.extensionAttribute1)"
extensionAttribute3 = "$($_.extensionAttribute3)"
initials = "$($_.initials)";
#additionalAttributeName = "$($_.additionalAttributeName)"
#additionalAttributeName = "$($_.additionalAttributeName)"
#additionalAttributeName = "$($_.additionalAttributeName)"
#additionalAttributeName = "$($_.additionalAttributeName)"
#additionalAttributeName = "$($_.additionalAttributeName)"
}
}
The top row of your .csv file would look like the following for this example:
samAccountname,description,extensionAttribute1,extensionAttribute3,initials

Line break issue when configuring "send on behalf of"

I have a script to set send on behalf of permissions in Exchange Management Shell, but when you try and use it it fails because the output of the first part is too long and truncates over 2 lines.
First thing we do is build our array from lists of people and put them into some variables to pass:
function Add-Send ($mailbox, $target) {
#"Granting send on behalf for $mailbox to $target"
Set-Mailbox -Identity $mailbox -GrantSendOnBehalfTo #{ Add = $target }
}
We pass a long list as the $target and the maibox name is $mailbox and if we output the text we get:
Set-Mailbox -Identity "mr.jeff" -GrantSendOnBehalfTo #{ Add = "alan.alanson", "bob.bobson", "steve.stevenson" }
All fine and good but if there are more than N characters in the output then we get a line break:
Set-Mailbox -Identity "mr.jeff" -GrantSendOnBehalfTo #{ Add = "alan.alanson", "bob.bobson", "steve.stevenson", ...
..., "cath.cathdotir" }
When you run this script with the overlength output, then command fails as the output which should be passed to the CLI is passed over more than one line. PowerShell treats each line as a separate command, and they obviously fail with bad syntax.
Our string is output from an array that we build like this:
function Send-Array ($mailbox) {
$target = Get-Content ".\list\dpt1.txt"
$target += Get-Content ".\list\$mailbox.txt"
$target += Get-Content ".\list\dpt2.txt"
$target = $target | Select-Object -Unique
$separator = '", "'
$target= $target -replace '^|$','"' -join ','
Add-Send $mailbox $target
}
This gives us an array with strings that look like:
"alan.alanson", "bob.bobson", "steve.stevenson"
From here I am at a loss any ideas would be much appreciated.
The obvious solution would be to pass the names one at a time, but due to a gotcha with Exchange Server every time you set send on behalf of permissions with PowerShell it wipes the existing permissions, so you only end up with he last person granted permissions being able to send on behalf of.
See this link for help with your underlying issue.
Very basically, you will have to:
get the DistinguishedName of the user you need to add
store the current value of GrantSendOnBehalfTo in a variable
append the new user's distinguished name to the list
replace GrantSendOnBehalfTo with the new list
Afterwards you should not need to pass endless strings to the EMS (I hope so).

powershell set-adcomputer netbootguid

quick question. I want to update the netbootguid of an active directory computer object. The following though doesn't seem to work.
Set-ADComputer -identity $someComputerName -add#{'netbootGUID' = $theguidhere}
where $guid = "00000000-0000-0000-0000-001CC082A15C" #a mac address
I get the following error:
Set-ADComputer : A value for the attribute was not in the acceptable range of values
Any idea what i am doing wrong and how i can correct it?
try declaring the type of $guid ( I can't test it now):
[guid]$guid = "00000000-0000-0000-0000-001CC082A15C"
and try:
Set-ADComputer -identity $someComputerName -add#{'netbootGUID' = $guid.tobytearray()

Assign a Get-WebAppPoolState returned value to a variable in Powershell

This code:
import-module WebAdministration
Get-WebAppPoolState AppPoolName
Produces the following output:
Value
- -
Stopped
But this code:
import-module WebAdministration
$state = Get-WebAppPoolState AppPoolName
WRITE-HOST $state
Produces this output:
Microsoft.IIs.PowerShell.Framework.CodeProperty
When I get the state of the App Pool using Get-WebAppPoolState, I need a boolean value of some sort to assign to the variable so I can use it in a conditional statement.
I cant use the Microsoft.IIs.PowerShell.Framework.CodeProperty line.
How do I correct this?
Get-WebAppPoolState is not returning a string but an object of type CodeProperty. You'll want the Value property from that object, i.e.:
$state = (Get-WebAppPoolState AppPoolName).Value;
I presume some display converter is kicking in the first case when it gets written to output which is why Stopped is displayed but not for writing to host so you get the default object representation (which is the type name) instead.
Not tested, but does this work better?
$state = $(Get-WebAppPoolState AppPoolName)
Another approach is to use the Select-Object cmdlet with ExpandProperty to get the value of 1 or more properties from an object.
$pool = "app-pool-name"
$state = Get-WebAppPoolState $pool | Select -ExpandProperty Value
Write-Host $state