function Update-Property {
<#
.Synopsis
Updates
properties of objects or values of hashtables.
.DESCRIPTION
This function
creates or sets properties of objects or values of hashtables. If a property or
key doesn't exist then the function will create that and assign the given value
to it.
If the
property or key exists then - depending on the type of its value - it's going
to do one of the following actions:
- if the
existing value is an integer and the new value is an integer then it adds the
new value to the existing one
- in other
cases the function converts the existing value to a collection if it's not
already that and adds the new value as a new element to that collection. If the
new value is already
among the
existing elements then it will skip adding the new element to it.
- if the
-Force switch is used then the existing value is going to be overwritten by the
new value
This
function is meant to extend the scope and functionality of Add-Member.
.EXAMPLE
$splatting =
@{}; Update-Property -Object $splatting -PropName DisplayName -Value 'Tibor
Soos'; Update-Property -Object $splatting -PropName Replace -Value
@{proxyAddresses = "SMTP:Soos.Tibor@hotmail.com"}
In this
example we prepare a hashtable $splatting for splatting the Set-ADUser cmdlet
to set the displayname and the proxyAddresses attribute of an AD user object.
.EXAMPLE
Update-Property -Object $splatting -PropName Replace -Value
@{proxyAddresses = "smtp:SoosTibor@hotmail.com"} ; $splatting.Replace
In this
example we add a secondary SMTP address to the splatting hashtable under its
Replace key.
.EXAMPLE
Update-Property -Object $splatting.Replace -PropName proxyAddresses
-Value "smtp:tibor.soos@hotmail.com" -PassThru
In this
example we add another secondary SMTP address to the splatting hashtable
directly under its Replace.proxyAddresses key. Using the -PassThru switch we
get back the updates hashtable under the Replace key.
.EXAMPLE
$obj =
[pscustomobject] @{Prop1 = "Text"; Prop3 = "Obsolete"};
Update-Property -Object $obj -PropName Prop2; Update-Property -Object $obj
-PropName Prop3 -Value Fresh -Force; Update-Property -Object $obj -PropName
Prop1 -Value NewText -PassThru
In this
example we update an object in $obj 3 times. First we create a new property
Prop2, then we overwrite the property 'Prop3' to 'Fresh', then we extend the
existing value of Prop1 by converting it to a collection and adding 'NewText'
to it as a new element.
.INPUTS
hashtable or
psobject
.OUTPUTS
The updated
input object if the -PassThru switch is used.
#>
[cmdletbinding()]
param(
# Input object,
either a hashtable or a PSObject
[psobject]
$Object,
# Name of the
property or key to update
[string] $PropName,
# The new value to
include in the update process. By default it's 1.
[psobject]
$Value
=
1,
# Switch to output
the update input object
[switch] $PassThru,
# Switch to do an
overwrite
[switch] $Force
)
if($null
-eq
$Object){
Write-Error
"No
object - update propery"
return
}
if($Object
-is
[hashtable]
-and
!$Object.containskey($PropName)){
$Object.$PropName
=
$Value
}
elseif($Object
-isnot
[hashtable]
-and
$Object.psobject.Properties.Name
-notcontains
$PropName){
Add-Member
-InputObject
$Object
-MemberType
NoteProperty -Name
$PropName
-Value
$Value
}
elseif($Force){
$Object.$PropName
=
$Value
}
elseif($Object.$PropName
-is
[int]
-and
$Value
-is
[int]){
$Object.$PropName
+=
$Value
}
elseif($Object.$PropName
-is
[string]){
if($Value
-ne
$Object.$PropName){
$Object.$PropName
=
@($Object.$PropName)
+
$Value
}
}
elseif($Object.$PropName
-is
[collections.ilist]){
if($Object.$PropName
-is
[collections.ilist]
-and
$Object.$PropName.count
-gt
0
-and
$Object.$PropName[0]
-is
[hashtable]){
if($Value
-is
[collections.ilist]
-and
$Value.count
-gt
0
-and
$Value[0]
-is
[hashtable]){
$existingKeys
=
$Object.$PropName
|
&{process{
{$_.Keys}}}
if($existingKeys
-notcontains
($Value.keys
|
Select-Object
-First
1)){
$Object.$PropName +=
$Value
}
else{
$equalfound
=
$false
foreach($v
in
$Object.$PropName){
$difffound
=
$false
foreach($k
in
$v.keys){
if($v.$k
-ne
$Value[0].$k){
$difffound
=
$true
break
}
}
if(!$difffound){
$equalfound
=
$true
break
}
}
if(!$equalfound){
$Object.$PropName
+=
$Value
}
}
}
}
else{
foreach($v
in
$Value){
if($Object.$PropName
-notcontains
$v){
$Object.$PropName +=
$v
}
}
}
}
elseif($Object.$PropName
-is
[System.Collections.Hashtable]
-and
$Value
-is
[System.Collections.Hashtable]){
$keys
=
[object[]]
$Value.keys
foreach($key
in
$keys){
if($Object.$PropName.containskey($key)){
if($Object.$PropName.$key
-notcontains
$Value.$key){
if($null
-ne
$Object.$PropName.$key){
$Object.$PropName.$key
=
@($Object.$PropName.$key)
+
$Value.$key
}
else{
$Object.$PropName.$key
=
$Value.$key
}
}
}
else{
$Object.$PropName.$key =
$Value.$key
}
}
}
else{
$Object.$PropName
=
@($Object.$PropName)
+
$Value
}
if($PassThru){
$Object
}
}