Powershell accessing embedded properties - powershell

I am working in Powershell and the result of some queries return a collection member like this (note that this is shortened from the actual output):
SmsProviderObjectPath : SMS_SCI_SysResUse.FileType=2,ItemName="[\"Display=\\\\SERVER1.MYDOMAIN.ORG\\\"]MSWNET:[\"SMS_SITE=MBC\"]\\\\SERVER1.MYDOMAIN.ORG\\,SMS Distribution Point",ItemType="System
Resource Usage",SiteCode="MBC"
FileType : 2
ItemName : ["Display=\\SERVER1.MYDOMAIN.ORG\"]MSWNET:["SMS_SITE=MBC"]\\SERVER1.MYDOMAIN.ORG\,SMS Distribution Point
ItemType : System Resource Usage
NALPath : ["Display=\\SERVER1.MYDOMAIN.ORG\"]MSWNET:["SMS_SITE=MBC"]\\SERVER1.MYDOMAIN.ORG\
NALType : Windows NT Server
NetworkOSPath : \\SERVER1.MYDOMAIN.ORG
PropLists : {BindExcept, Protected Boundary, SourceDistributionPoints, SourceDPRanks...}
Props : {BITS download, Server Remote Name, PreStagingAllowed, SslState...}
RoleCount : 2
RoleName : SMS Distribution Point
SiteCode : MBC
SslState : 0
Type : 8
PSComputerName : prim-serv.MYDOMAIN.org
PSShowComputerName : False
ManagedObject : \\prim-serv\root\sms\site_MBC:SMS_SCI_SysResUse.FileType=2,ItemName="[\"Display=\\\\SERVER1.MYDOMAIN.ORG\\\"]MSWNET:[\"SMS_SITE=MBC\"]\\\\SERVER1.MYDOMAIN.ORG\\,SMS
Distribution Point",ItemType="System Resource Usage",SiteCode="MBC"
OverridingObjectClass : SMS_SCI_SysResUse
RegMultiStringLists : {}
SecurityVerbs : -1
ObjectClass : SMS_SCI_SysResUse
Properties :
instance of SMS_EmbeddedProperty
{
PropertyName = "IsPXE";
Value = 0;
Value1 = "";
Value2 = "";
},
instance of SMS_EmbeddedProperty
{
PropertyName = "IsActive";
Value = 0;
Value1 = "";
Value2 = "";
},
instance of SMS_EmbeddedProperty
{
PropertyName = "IsPullDP";
Value = 0;
Value1 = "";
Value2 = "";
},
instance of SMS_EmbeddedProperty
{
PropertyName = "IsMulticast";
Value = 0;
Value1 = "";
Value2 = "";
},
instance of SMS_EmbeddedProperty
{
PropertyName = "LastIISConfigCheckTime";
Value = 1490896883;
Value1 = "";
Value2 = "";
}};
RoleCount = 2;
RoleName = "SMS Distribution Point";
SiteCode = "MBC";
SslState = 0;
Type = 8;
};
PropertyNames : {FileType, ItemName, ItemType, NALPath...}
MethodNames :
MethodList : {}
PropertyList : {[FileType, 2], [ItemName, ["Display=\\SERVER1.MYDOMAIN.ORG\"]MSWNET:["SMS_SITE=MBC"]\\SERVER1.MYDOMAIN.ORG\,SMS Distribution Point], [ItemType, System Resource Usage],
[NALPath, ["Display=\\SERVER1.MYDOMAIN.ORG\"]MSWNET:["SMS_SITE=MBC"]\\SERVER1.MYDOMAIN.ORG\]...}
UniqueIdentifier : 16242167-3aac-4b79-ad5b-2c8030922ba5
ParentResultObject :
GlobalDisplayString :
AutoCommit : False
AutoRefresh : False
UserDataObject :
ConnectionManager : Microsoft.ConfigurationManagement.PowerShell.Provider.CmdletWqlConnectionManager
TraceProperties : True
NamedValueDictionary : {[AllProviderLocations, System.Collections.Generic.List`1[System.Management.ManagementBaseObject]], [ProviderLocation,
\\prim-serv\ROOT\sms:SMS_ProviderLocation.Machine="prim-serv.MYDOMAIN.org",SiteCode="MBC"], [ProviderMachineName, prim-serv.MYDOMAIN.org], [Connection,
\\prim-serv.MYDOMAIN.org\root\sms\site_MBC]...}
AsyncOperationData :
RetainObjectLock : False
I can access many of the items listed, such as "NetworkOSPath" and "RoleName" with code like this:
$myDP = $DP.NetworkOSPath
I am at a loss how to reference items listed in the Properties area such as:
IsPXE, IsPullDP and the values associated with them.
I can get a listing of them using the command: $dp.EmbeddedProperties | format-list *
This produces a listing of Keys and Values:
Key : AllowInternetClients
Value :
instance of SMS_EmbeddedProperty
{
PropertyName = "AllowInternetClients";
Value = 0;
Value1 = "";
Value2 = "";
};
Key : BITS download
Value :
instance of SMS_EmbeddedProperty
{
PropertyName = "BITS download";
Value = 1;
Value1 = "";
Value2 = "";
};
In an effort to just list a specific key, I've tried the following without success:
foreach ($DP in $DPList) {$DP.EmbeddedProperties | select-object -expandproperty IsPXE }
foreach ($DP in $DPList) {$DP.EmbeddedProperties | Select-Object where Name = "IsPXE"}
foreach ($DP in $DPList) {$DP.EmbeddedProperties | Select-Object IsPXE}
Is there a way to reference the key and their associated values so that I can assign them to variables inside of my script?

It looks like the properties section is just text. Was the contents of ($dp.EmbeddedProperties | format-list *) wrapped in quotes when it was added to $dp? Make previous sections of your script are not dumping text into your object. Keep objects as objects as much as possible.
I had issues like this when working with outputs like this
get-adgroupmember -identity $name | select stuff
until I switched to a better method
(get-adgroupmember -identity $name).stuff

You were so close with $dp.EmbeddedProperties. Just keep dotting and you'll get there. Once you get the value you are looking for, you can add it to an object. Here's an example:
$dp = Get-CMDistributionPoint
$NewObj = #()
ForEach ($d in $dp)
{
$ServerName = $d.NetworkOSPath
$IsPXE = $d.embeddedproperties.IsPXE.Value
$NewObj += [pscustomObject]#{ ServerName = $ServerName; IsPXE = $IsPXE }
}
$NewObj | Out-GridView
BE CAREFUL - Once you dot-note passed EmbeddedProperties, you enter the eerie world of Case-Sensitivity! If you don't have it correct, you get NOTHING! I'm not sure why. perhaps it has something to do with the .NET's System.Collections.Generic.Dictionary class and Case-Sensitive String Keys?
IE
$d.embeddedproperties.IsPXE.Value ##This works.
$d.embeddedproperties.IsPXe.Value ##This does not work.

Related

Get the same value from all indices of an array in powershell

I try to get a value that is repeated in all the indices of an array but I can't get it.
What I need to get is the RuleName value of each index in the array, so that the result will be:
P005DYQ, P005DYD
My array is the following:
PS C:\Users\admin> $array
instance of SMS_CollectionRuleDirect
{
ResourceClassName = "R_System";
ResourceID = 79023;
RuleName = "P005DYQ";
};
instance of SMS_CollectionRuleDirect
{
ResourceClassName = "R_System";
ResourceID = 9024;
RuleName = "P005DYD";
};
How can I get the RuleName values so that the result is P005DYQ and P005DYD?

Combine two dictionaries and replace keys with values in powershell

i have two arrays that look like this:
$ht1 = #{
"computer55" = "port33"
“computer1” = “port1”
“computer2” = “port2”
}
and
$ht2 = #{
"A1:B2:C3:D4:E5:F6" = "port1"
"A2:B3:C4:D5:E6:F7" = "port2"
"A3:B4:C5:D6:E7:F8" = "port33"
"A4:B4:C5:D6:E7:F8" = "port45"
}
The first one is one I manually hardcode into the script, I have an actual list of device names and what port they are plugged into on a switch. The second one is generated with a switch script that logs in, gets the mac address table and records it as a hashtable.
My desired outcome is this, if there is a port with an assigned name, replace the port name with the device name.
$ht3(or any name) = #{
"A1:B2:C3:D4:E5:F6" = "computer1"
"A2:B3:C4:D5:E6:F7" = "computer2"
"A3:B4:C5:D6:E7:F8" = "computer55"
"A4:B4:C5:D6:E7:F8" = "port45"
}
I've somehow spent about a day on this(... pretty much the first powershell script I've ever came up with) and my end result is always the same, I end up merging two hashtables and pair the port with the computer name and not the mac address with the computer name. any direction is appreciated
Important note, the .ContainsValue method is case sensitive, if you want a case insensitive search use one of the following:
if($val = [string]$ht1.Keys.Where({$ht1[$_] -eq $ht2[$key]}))
{
#{$key = $val}
continue
}
if($ht1.Values -contains $ht2[$key])
{
...
}
if($ht2[$key] -in $ht1.Values)
{
...
}
Code
$ht1 = #{
computer55 = 'port33'
computer1 = 'port1'
computer2 = 'port2'
}
$ht2 = #{
'A1:B2:C3:D4:E5:F6' = 'port1'
'A2:B3:C4:D5:E6:F7' = 'port2'
'A3:B4:C5:D6:E7:F8' = 'port33'
'A4:B4:C5:D6:E7:F8' = 'port45'
}
$result = foreach($key in $ht2.Keys)
{
if($ht1.ContainsValue($ht2[$key]))
{
#{$key = [string]$ht1.Keys.Where({$ht1[$_] -eq $ht2[$key]})}
continue
}
#{$key = $ht2[$key]}
}
Looking at $result yields:
Name Value
---- -----
A1:B2:C3:D4:E5:F6 computer1
A3:B4:C5:D6:E7:F8 computer55
A4:B4:C5:D6:E7:F8 port45
A2:B3:C4:D5:E6:F7 computer2
[string]$ht1.Keys.Where({$ht1[$_] -eq $ht2[$key]})
Could also be the following, though, I'm not sure which one would be more efficient:
$ht1.GetEnumerator().Where({$_.Value -eq $ht2[$key]}).Key

How to add data row to object

Below is the result of an API call via Invoke-Restmethod
And output of $test.result.organizationContext is as follows
How can I add an line item to this "organizationContext" object with values for the different attributes like " name", "id" ?
If we assume that you already have the values you want to add defined in variables, you can create a new custom object and then effectively, yet inefficiently, add it to the array.
$newOrganizationContext = [pscustomobject]#{
classificationId = $classificationId
group = $group
id = $id
isGroupSeparator = $isGroupSeparator
name = $name
objectId = $objectId
path = $path
subClass = $subClass
synchronized = $synchronized
type = $type
}
$test.result.organizationContext += $newOrganizationContext

How can I get the presentation details/rendering properties when using Find-Item command?

I want to get the renderings (presentation details) of each items.
I have tried using Get-Rendering, but it doesn't work.
$criteria = #(
#{ Filter = "Equals"; Field = "_template"; Value = "{9A43A639-4209-49B9-8024-766A9E1AB03E}"; },
#{ Filter = "DescendantOf"; Value = (Get-Item "master:/content/"); }
)
$props = #{
Index = "sitecore_master_index"
Criteria = $criteria
}
Find-Item #props | Get-Rendering -FinalLayout
It throws the following error:
The input object cannot be bound to any parameters for the command
either because the command does not take pipeline input or the input
and its properties do not match any of the parameters that take
pipeline input.
What am I missing?

PowerShell Export-Csv repeating last value in output - solution

SCENARIO:
In my script, I create an object, add the common info, and then updated the sub info for each object in a loop and add that object to an array of objects.
My verbose shows that the values are correct in the object added to the array (reporting the last item in the array), but Export-Csv repeats the last object values.
I am able to resolve this if I create a new object each time. Reusing the same object repeats the last value, even though I can see it correct when I select * on the objects in the array. There must be something about the array object, such as a guid that is duplicated for the same object.
PowerShell 5.1 verified on Windows 7, Windows 2008R2, Windows 2010R2
SOLUTION:
Do not reuse an object when adding it to an array of objects.
OUTPUT:
#TYPE MyGpoSetting
"SetName","SetCategory","SetType","SetState","SetValue","SetData","SetNote","SubName","SubState","SubValue","GpoDomain","GpoName","GpoLinks","GpoGuid"
"SetName","SetCategory","SetType","SetState","SetValue","SetData","SetNote","SubName3","SubState3","SubValue3","GpoDomain","GpoName","GpoLinks","GpoGuid"
"SetName","SetCategory","SetType","SetState","SetValue","SetData","SetNote","SubName3","SubState3","SubValue3","GpoDomain","GpoName","GpoLinks","GpoGuid"
"SetName","SetCategory","SetType","SetState","SetValue","SetData","SetNote","SubName3","SubState3","SubValue3","GpoDomain","GpoName","GpoLinks","GpoGuid"
SCRIPT:
Add-Type -TypeDefinition #"
public struct MyGpoSetting
{
public string SetName;
public string SetCategory;
public string SetType;
public string SetState;
public string SetValue;
public string SetData;
public string SetNote;
public string SubName;
public string SubState;
public string SubValue;
public string GpoDomain;
public string GpoName;
public string GpoLinks;
public string GpoGuid;
}
"#
$aoMyGpoSetting = #();
$oMyGpoSetting = New-Object -TypeName 'MyGpoSetting';
$oMyGpoSetting.SetName = 'SetName';
$oMyGpoSetting.SetCategory = 'SetCategory';
$oMyGpoSetting.SetType = 'SetType';
$oMyGpoSetting.SetState = 'SetState';
$oMyGpoSetting.SetValue = 'SetValue';
$oMyGpoSetting.SetData = 'SetData';
$oMyGpoSetting.SetNote = 'SetNote';
$oMyGpoSetting.SubName = 'SubName1';
$oMyGpoSetting.SubState = 'SubState1';
$oMyGpoSetting.SubValue = 'SubValue1';
$oMyGpoSetting.GpoDomain = 'GpoDomain';
$oMyGpoSetting.GpoName = 'GpoName';
$oMyGpoSetting.GpoLinks = 'GpoLinks';
$oMyGpoSetting.GpoGuid = 'GpoGuid';
$aoMyGpoSetting += $oMyGpoSetting;
#--- $oMyGpoSetting = New-Object -TypeName 'MyGpoSetting';
$oMyGpoSetting.SetName = 'SetName';
$oMyGpoSetting.SetCategory = 'SetCategory';
$oMyGpoSetting.SetType = 'SetType';
$oMyGpoSetting.SetState = 'SetState';
$oMyGpoSetting.SetValue = 'SetValue';
$oMyGpoSetting.SetData = 'SetData';
$oMyGpoSetting.SetNote = 'SetNote';
$oMyGpoSetting.SubName = 'SubName2';
$oMyGpoSetting.SubState = 'SubState2';
$oMyGpoSetting.SubValue = 'SubValue2';
$oMyGpoSetting.GpoDomain = 'GpoDomain';
$oMyGpoSetting.GpoName = 'GpoName';
$oMyGpoSetting.GpoLinks = 'GpoLinks';
$oMyGpoSetting.GpoGuid = 'GpoGuid';
$aoMyGpoSetting += $oMyGpoSetting;
#--- $oMyGpoSetting = New-Object -TypeName 'MyGpoSetting';
$oMyGpoSetting.SetName = 'SetName';
$oMyGpoSetting.SetCategory = 'SetCategory';
$oMyGpoSetting.SetType = 'SetType';
$oMyGpoSetting.SetState = 'SetState';
$oMyGpoSetting.SetValue = 'SetValue';
$oMyGpoSetting.SetData = 'SetData';
$oMyGpoSetting.SetNote = 'SetNote';
$oMyGpoSetting.SubName = 'SubName3';
$oMyGpoSetting.SubState = 'SubState3';
$oMyGpoSetting.SubValue = 'SubValue3';
$oMyGpoSetting.GpoDomain = 'GpoDomain';
$oMyGpoSetting.GpoName = 'GpoName';
$oMyGpoSetting.GpoLinks = 'GpoLinks';
$oMyGpoSetting.GpoGuid = 'GpoGuid';
$aoMyGpoSetting += $oMyGpoSetting;
$aoMyGpoSetting | Export-Csv -Path 'c:\temp\export.csv' -Encoding 'ASCII';
This is working as expected. Adding the object to the array (+=) doesn't copy the object, but instead adds a reference/pointer to it in the next 'slot'. So in effect you are adding three references to the same object. It's like having 3 entries in your phonebook for your best friend:
John Smith - 01234 5678
Jonnie - 01234 5678
Smith, John - 01234 5678
Whichever one you call, gets you through to the exact same person.
Similarly, each time PowerShell displays an object from your array, it is actually going back to the same source object and showing it to you. That is why all of them have the same properties as the last one you added - they are in fact all that same one.
As you've discovered, creating a new object each time is the way to proceed.