Getting data out of structure not working - powershell

I'm trying to get the data out of the data structure, and I can see it's in there, but the variable the info is assigned to is null.
Let me know if you need more info for the method that assigns $SizeBasedVideoStringDevice, but it looks like this:
$SizeBasedVideoStringDevice:
[Object[7]]:
[0]:#{Key=LOAD_MEDIA;VALUE=SYSTEM.OBJECT[]}
[1]:#{KEY=LOAD_MEDIAB;VALUE=}
[2]:#{KEY=LOAD_MEDIAC;VALUE=}
[3]:#{KEY=LOAD_MEDIAD;VALUE=SYSTEM.OBJECT[]}
...
So some of them have a Value, which is fine.
When I look closer at that first value, it looks like this:
Value: [Object[5]]
[0]: "LoadDialog.MediaA"
[1]: "LoadDialog.MediaB"
[2]: "LoadDialog.MediaC"
...
I have the following code, and for some reason it's not finding that first one. Once I get the data out, I will loop thru and process each Value.
$tmp = "LOAD_MEDIA" #this will match first in data structure
$sizeBasedVideoString = $SizeBasedVideoStringDevice.where{$_Key -eq $tmp}.Value ###this is null
if($null -ne $sizeBasedVideoString)
{
$resultDPS_sized = New-Object System.Collections.Generic.List[string]
foreach($vid in $sizeBasedVideoString)
{
#get vid location
$temp = ProcessDPSMDB -mdbLookupString $vid -mdbFilePath $dpsMdbPathFull
$resultDPS_sized.Add($temp)
}
}
This is using PowerShell 5.1 and VSCode.

Related

How do I populate an unknown number of variables from user input dynamically in powershell?

I am trying to figure out how to populate an unknown number of variables based on user input (writing a script that obtains certificates from a CA, and sometimes these certificates contain more than one name (SANs) and it is impossible to know how many so this needs to be dynamic).
I know I start with setting up params like this:
[CmdletBinding()]
Param(
[Parameter(Mandatory=$True)]
[string[]]$SANs
)
And then I need to somehow take those values and assign them to $san1, $san2, $san3 and so on.
Being new to programming, I am not even sure what to call this. Would you use a foreach loop to somehow populate these variables?
ForEach ($SAN in $SANs) {
what do I do here?
}
The end result is a need to populate a string with these variables like dns=$san1&dns=$san2&dns=$san3 etc...
Functions and scripts can take parameters. The parameter block in your example looked like...
function foo {
Param([string[]]$SANs)
}
That parameter, $SANs, is an array of strings. A single string would look like this...
$stuff = 'barf'
An array of strings looks like this...
$stuff = #('barf', 'toot', 'ruff', 'meow')
So far so good? If you need to get each of the things in the array, you'd use a loop...
foreach ($thing in $stuff) { write-output $thing }
...for example...
$san_declaration
foreach ($thing in $stuff) {
if ($san_declaration.length -eq 0) {
$san_declaration = "dns=${thing}"
} else {
$san_declaration += "&dns=${thing}"
}
}
Now, if you (not that you asked) happen to be calling Get-Certificate, just remember the SANs parameter is a string array. In that case, you'd just pass in the string array instead of creating the string like you were doing.
Get-Certificate -DnsName $stuff

Getting a FieldLookupValue from Sharepoint in Powershell

Looking on the net I came up with this 2 functions to request Sharepoint using this 3 DLL with powershell :
Microsoft.SharePoint.Client.dll
Microsoft.SharePoint.Client.Taxonomy.dll
Microsoft.SharePoint.Client.Runtime.dll
This function is used to get all items from a list
Function Get-ListItems([Microsoft.SharePoint.Client.ClientContext]$Context, [String]$ListTitle) {
$list = $Context.Web.Lists.GetByTitle($listTitle)
$qry = [Microsoft.SharePoint.Client.CamlQuery]::CreateAllItemsQuery()
$items = $list.GetItems($qry)
$Context.Load($items)
$Context.ExecuteQuery()
return $items
}
And this one to work the list :
Function getChangeListsFromSharepoint(){
$context = New-Object Microsoft.SharePoint.Client.ClientContext($Url)
$items = Get-ListItems -Context $context -ListTitle $listName
foreach($item in $items)
{
/** Working HERE **/
}
$context.Dispose()
}
Now when I'm displaying all item content using Write-Host $item.Fields I've got something like this :
[Title,"blabla"]
...
[SpecialField,Microsoft.SharePoint.Client.FieldLookupValue[]]
[OtherField,Microsoft.SharePoint.Client.FieldLookupValue]
I'm trying to get the value of SpecialField and OtherField. To do so I'm using $item["SpecialField"].LookupValue. And I've got no problem. But when I'm doing it on OtherField the value is empty. If I try to use $item["OtherField"].LookupID the value is not empty and I've got an ID. How can I get the value behind this ID ? What's the difference between FieldLookupValue[] and FieldLookupValue ?
FieldLookupValue[] is a multi-value lookup column.
It has property Allow multiple values set to true and contains an array of items.
So, $item["OtherField"].LookupValue will not work here, you need to iterate it over as below:
#multi-value lookup
$mvLookup = [Microsoft.SharePoint.Client.FieldLookupValue[]] $item["OtherField"]
$mvLookup |% { "Lookup Value: $($_.LookupId):$($_.LookupValue)" }
which results in values as below:
FieldLookupValue is a single value lookup column. It has the Allow multiple values set to false and contains a single item. So, $item["SpecialField"].LookupValue will work here
So the solution was easy : my user didn't had the rights to explore the (field)list because it was from a (sharepoint)list on wich he didn't had any rights. What is strange is that on the website the value was visible but it's not when using powershell.

PowerShell Variable

I am looking up data and then want to add that to some kind of list which I can reference, for example if my data looked like this:
Name - John
Last Name - Doe
Age - 55
I would want to store that in a list and be able to do foreach $member in $myList and be able to print $member.Name
Hope that makes sense, not sure what the best way to do this is, would it be creating an object? or using a hashtable?
You can use a PowerShell Hashtable for this:
$NameObject= #{
'Name'='John'
'LastName'='Doe'
'Age'='55'
}
You can do this inside of a loop to add your data like so, to create a PowerShell Object.
$NameObjectCollection = foreach($Object in $MyData)
{
#Add Data to Object
[PSCustomObject] $NameObject= #{
'Name'=$Object.Property1
'LastName'=$Object.Property2
'Age'=$Object.Property3
}
#Output object
$NameObject
}
#Now you can loop over this data
foreach($NameObject in $NameObjectCollection)
{
#Access the properties of the NameObject`
$NameObject.Name
$NameObject.LastName
$NameObject.Age
}

PowerShell Switch not working with hyphenation

I'm creating a series of new PSObjects, from a CSV import, and then adding them to $new. I'm using a switch to try and set the value for the "Notes" property, as the object is being created\added, and I've run into something 'hinky'.
When I run this...
$import = Import-Csv c:\somerandom.csv
$new = #()
foreach ($Item in $Import) {
$obj = New-Object PsObject -Property #{
Name = $item.Name
Description = $Item.Description
Quantity = $Item.Quantity
Vendor = $Item.Vendor
SubCategory = "Misc"
Notes = ""
}
switch ($obj.Name) {
"iPod" { $obj.Notes = "Burn with the rest of the Apple garbage"}
"nVidia GTX 780ti" { $obj.Notes = "Steal immediately!" }
default { $obj.Notes= "Sorry man... I have no idea what that is"}
}
$new += $obj
}
... it works as expected. All of the entries from $import, are recreated in $new, with the addition of my "SubCategory" and "Notes" noteproperties (iPod gets burn tag, 780ti slated to be stolen). But when I run with the following as the switch...
switch ($obj.Name) {
'SOFM090-107-01-PF-R' { $obj.Notes = "Burn with the rest of the Apple garbage"}
'M094-107-01-PF-R' { $obj.Notes = "Steal immediately!" }
default { $obj.Notes = "Sorry man... I have no idea what that is"}
}
... It sets all the entries to the 'default' setting on the switch. I tried running the switch with a non-hyphenated name for one entry, and a hyphenated entry for the other, and only the hyphenated version was set properly.
The above code is altered from the actual code, but it properly illustrates what I'm trying to do. I need to add a noteproperty that is based off a list of part numbers, and will fill in the "Notes" entry with a tag of my choosing.
I've tried it with single quotes, double quotes, using the -wildcard and replacing the switch hyphens with *'s, and putting the ` character in before the -'s. Nothing seems to be working.
There's nothing wrong with the code, so the problem must lie in the data. I verified that it works fine with a CSV file that has those exact hyphenated values in the "Name" column.
If the switch doesn't work with the hyphenated names, then the values being imported into the Name property don't match what you have in the switch statement. It's a good idea to always post the data you're working with, or a sample of it, because often that's the source of the problem. Even when it isn't, it helps other people understand what you're trying to accomplish and what your code does. Since we don't have the data, I can suggest a few likely possibilities:
You're manually typing the names into the switch statement, and they look like what's in the CSV, but don't actually match, e.g. you're confusing O with 0 because they look the same in the font you're working with. I'd have suspected something like an en-dash instead of a hyphen, but you say you tried replacing the hyphens with wildcards
You have trailing spaces
You're single-quoting the hyphenated names in the CSV file (Import-Csv only understands double quotes; single quotes would be included in the value).
Here are a couple of things you can try to help identify why the data doesn't match (separately, not both together):
Replace switch ($obj.Name) { with switch -regex ($obj.Name) {
Use the following code to show you exactly what PowerShell is seeing in the Name property for each item and which switch conditions are being executed:
Write-Host -NoNewline "[$($obj.Name)] "
switch ($obj.Name) {
'SOFM090-107-01-PF-R' {Write-Host 'burn'; $obj.Notes = "Burn with the rest of the Apple garbage"}
'M094-107-01-PF-R' {Write-Host 'steal'; $obj.Notes = "Steal immediately!"}
default {Write-Host 'sorry'; $obj.Notes = "Sorry man... I have no idea what that is"}
}
If you post the data, we'll probably be able to tell you exactly why it's not working. But I can pretty much guarantee you that if you're using that code, the problem is that the imported Name values that aren't being matched with the right Notes values are in some way not the same as what you have in the switch conditions.

Passing custom object array to a function

I'm trying to pass an array of custom objects to a function for further processing of these objects.
Here's the function where I create my custom object array:
Function GetNetworkAdapterList
{
# Get a list of available Adapters
$hnet = New-Object -ComObject HNetCfg.HNetShare
$netAdapters = #()
foreach ($i in $hnet.EnumEveryConnection)
{
$netconprop = $hnet.NetConnectionProps($i)
$inetconf = $hnet.INetSharingConfigurationForINetConnection($i)
$netAdapters += New-Object PsObject -Property #{
Index = $index
Guid = $netconprop.Guid
Name = $netconprop.Name
DeviceName = $netconprop.DeviceName
Status = $netconprop.Status
MediaType = $netconprop.MediaType
Characteristics = $netconprop.Characteristics
SharingEnabled = $inetconf.SharingEnabled
SharingConnectionType = $inetconf.SharingConnectionType
InternetFirewallEnabled = $inetconf.InternetFirewallEnabled
SharingConfigurationObject = $inetconf
}
$index++
}
return $netAdapters
}
Then in my main code I call above function like this:
$netAdapterList = GetNetworkAdapterList
The $netAdapterList returns the expected data, and I can do stuff like:
$netAdapterList | fl Name, DeviceName, Guid, SharingEnabled
So far so good.
Now I want to call a function passing in the $netAdapterList
I've created a dummy function like this:
Function ShowAdapters($netAdapterListParam)
{
$netAdapterListParam | fl Name, DeviceName, Guid, SharingEnabled
}
And when I invoke it like this:
ShowAdapters $netAdapterList
Nothing gets printed out.
I've tried changing the function's signature but still no luck:
Function ShowAdapters([Object[]]$netAdapterListParam)
Function ShowAdapters([Object]$netAdapterListParam)
Function ShowAdapters([PSObject[]]$netAdapterListParam)
Function ShowAdapters([array]$netAdapterListParam)
Anybody knows what I'm doing wrong? How can I get to my custom objects inside the function?
Thanks for your reply #Christian. Tried your steps, copy pasting bits and pieces into the shell and it indeed worked. However If i run the full .ps1 script is not printing out anything.
I've run the script in Powershell IDE setting breakpoints inside the ShowAdapters function, and $netAdapterListParam has indeed the expected custom objects array I'm passing in, so I've narrowed down the issue to be in the FL commandlet.
For some reason $netAdapterList | fl Name, DeviceName, Guid, SharingEnabled did not work for me, so I ended up using the following instead:
$formatted = $netAdapterListParam | fl Name, DeviceName, Guid, SharingEnabled | Out-String
Write-Host $formatted
That did the trick and the 4 properties were printed on the screen.
Lessons learned:
1) The Powershell IDE built into Win7 can be a very useful tool for debugging scripts
2) Format-List can be quirky when formatting custom objects, so Out-String was required.