Parsing strings before character in Powershell - powershell

I want to obtain the environment, project name and location from a string and store it in a variable in Powershell.
The string is in the format of env-project-location. Exampleuat-hrapp-westeurope
How do I filter the string and store the outputs in a variable?
$environment = "uat"
$project = "hrapp"
$location = "westeurope"

You don't need regex for this, assuming the string will always have the same naming convention a simple split would do it:
$environment, $project, $location = 'uat-hrapp-westeurope'.Split('-')

Santiago Squarzon's post got me thinking so I did a little googling and found that you can also use this method if you want a PSCustomObject vs independent variables.
Clear-Host
$Base = "uat-hrapp-westeurope"
$CFSArgs = #{PropertyNames = "Environment", "Project", "Location"
Delimiter = '-'}
$obj = $Base | ConvertFrom-String #CFSArgs
$Obj
Output:
Environment Project Location
----------- ------- --------
uat hrapp westeurope
PS> $obj | gm
TypeName: System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
Environment NoteProperty string Environment=uat
Location NoteProperty string Location=westeurope
Project NoteProperty string Project=hrapp

Related

Powershell - how to extract a value from Object[]

I'm trying to figure out how to grab the value associated with AzureWebJobsStorage variable from a Object[] in powershell. Here's the logic so far:
$azAppSettingsOutput = az functionapp config appsettings list --name somename --resource-group myResource --subscription subscription | ConvertFrom-Json
Write-Output $azAppSettingsOutput.GetType().name
Write-Output $azAppSettingsOutput | Get-Member
Write-Output $azAppSettingsOutput.name
This is the output I see:
PS C:\Users\me> .\test.ps1
Object[]
TypeName: System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
name NoteProperty string name=APPINSIGHTS_INSTRUMENTATIONKEY
slotSetting NoteProperty bool slotSetting=False
value NoteProperty string value=asdfasdf-asdf-asdf-asdf-asdf-asdf
APPINSIGHTS_INSTRUMENTATIONKEY
AzureWebJobsStorage
FUNCTIONS_EXTENSION_VERSION
FUNCTIONS_WORKER_RUNTIME
WEBSITE_RUN_FROM_PACKAGE
StorageTableName
PS C:\Users\me\>
I know I can loop through like this:
foreach($setting in $azAppSettingsOutput) {
Write-Output $setting.name
$value = $setting.value
And then I can add an if statement to check if the name matches "AzureWebJobsStorage" but just wondering if there's a simpler way.
Thanks.
Use the Where-Object cmdlet to filter your data:
$azAppSettingsOutput |Where-Object name -eq 'AzureWebJobsStorage'
This will filter out any objects except for those where the name property equals "AzureWebJobsStorage"

How use "Where-Object" condition with '[PScustomobject]'?

I have some code:
$output = [PSCustomObject]#{
Name = $ws.UsedRange.Columns.Item(1).Value2
Department = $ws.UsedRange.Columns.Item(3).Value2
}
$output | GM
TypeName: System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
Department NoteProperty System.Object[,] Department=System.Object[,]
Name NoteProperty System.Object[,] Name=System.Object[,]
I need to sort and filter my $output, but I can't. Nothing happens. Probably doing something wrong.
PS> $output
Name Department
---- ----------
{Numbers, 1,2,3,4,5,6,7...} {Sales,IT,Accounting,Developers...}
And my condition:
PS> $output | Sort-Object Department -Descending | Where-Object {$_.Department -eq "Sales"}
Name Department
---- ----------
{Numbers, 1,2,3,4,5,6,7...} {Sales,IT,Accounting,Developers...}
You created a single object with 2 properties, each of which contains all values of its associated column. Since Sort-Object and Where-Object sort and filter lists of objects by their properties there's nothing for these cmdlets to do here.
What you actually want to do is create one object per row.
$output = foreach ($row in $ws.UsedRange.Rows) {
[PSCustomObject]#{
Name = $row.Columns.Item(1).Value2
Department = $row.Columns.Item(3).Value2
}
}
Untested, since I don't have MS Office at hand here.

Enumerating a PSCustomObject

Does anyone have know of a way to "break" open a hash table source from a custom object. There is no .getenumerrator on a custom object but I have this hashtable: #{0=0.05; 1024=0.050; 51200=0.050; 512000=0.050; 1024000=0.045; 5120000=0.037}. I am pulling this information via the Azure RateCard REST API and need to break it down so I have access to each tier of rates to generate an accurate report of usage cost. Any suggestions? Sample outputs:
MeterId : d23a5753-ff85-4ddf-af28-8cc5cf2d3882
MeterName : Standard IO - Page Blob/Disk (GB)
MeterCategory : Storage
MeterSubCategory : Locally Redundant
Unit : GB
MeterTags : {}
MeterRegion :
MeterRates : #{0=0.05; 1024=0.050; 51200=0.050; 512000=0.050; 1024000=0.045; 5120000=0.037}
EffectiveDate : 2014-02-01T00:00:00Z
IncludedQuantity : 0.0
TypeName: System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
EffectiveDate NoteProperty System.String EffectiveDate=2014-02-01T00:00:00Z
IncludedQuantity NoteProperty System.Decimal IncludedQuantity=0.0
MeterCategory NoteProperty System.String MeterCategory=Storage
MeterId NoteProperty System.String MeterId=d23a5753-ff85-4ddf-af28-8cc5cf2d3882
MeterName NoteProperty System.String MeterName=Standard IO - Page Blob/Disk (GB)
MeterRates NoteProperty System.Management.Automation.PSCustomObject MeterRates=#{0=0.05; 1024=0.050; 51200=0.050; 512000=0.050; 1024000=0.045; 5120000=0.037}
MeterRegion NoteProperty System.String MeterRegion=
MeterSubCategory NoteProperty System.String MeterSubCategory=Locally Redundant
MeterTags NoteProperty System.Object[] MeterTags=System.Object[]
Unit NoteProperty System.String Unit=GB
Not sure what it is you mean by break open but this should give you the keys:
$object.MeterRates.keys
This will give you the values:
$object.MeterRates.keys | % {$object.MeterRates[$_]}
Are you after the total value? I guessing it might be something like this:
($object.MeterRates.keys | % {$object.MeterRates[$_] * $_} | Measure-Object -Sum).Sum
There's probably a better way to do this but my particular version of powershell hacking produced something like this -
$a = "#{0=0.05; 1024=0.050; 51200=0.050; 512000=0.050; 1024000=0.045; 5120000=0.037}"
$b = ConvertFrom-StringData `
-StringData $a.Replace("; ","`n").Replace("#","").Replace("{","").Replace("}","")
This presumes that the entire string is available, replace the semicolons with newlines, ditches the other bits and give it to ConvertFrom-StringData
Found this code on a similar question. Solves my problem:
$js | Get-Member -MemberType NoteProperty).Name

Powershell - how do I edit an existing property in a custom object

I looking for way how update noteproperty in existing psobject, for example I have system.array of psobjects ($a):
Group Assigment
----- ---------
Group1 Home
Group2 Office
Question is how update 'Home' to something other.
$a | gm:
TypeName: System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
Assigment NoteProperty System.String Assigment=Office
Group NoteProperty System.String Group=Group1
$a.GetType():
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
Thank you for future help.
It's not really clear what is your problem : select the good object or update it's value ?
$col=#()
$props=#{"group"="group1";"assignment"="home"}
$col += new-object pscustomobject -property $props
$props2=#{"group"="group2";"assignment"="office"}
$col += new-object pscustomobject -property $props2
#select object with home assignment
$rec=$col | where {$_.assignment -eq "home"}
#replace the value
$rec.assignment="elsewhere"
#display collection with updated value
$col
I don't think this works if $rec returns more than one record, though.
For example:
$rec = $col | where {$_.assignment -ne $null}
$rec.assignment = "elsewhere"
In theory that should set every individual record's assignment to "elsewhere" but it really just returns an error that the property "assignment" cannot be found on this object. I think for this to really work you'd need:
$recs = $col | where {$_.assignment -ne $null}
foreach ($r in $recs) {
$r.assignment="elsewhere"
}
Unless there's a way to set a value to every record in a given array, which I freely admit there may be.

Powershell, losing custom object attributes in hash table

I'm trying to make a collection of custom objects in powershell and store them in a hashtable. The problem is that the custom attributes disapear when I put the object into a hashtable.
$customObject = New-Object object
$customObject | Add-member -membertype noteproperty -name customValue -value "test"
Write-Host $customObject.customValue
$hashTable = #{}
$hashTable.add("custom", $customObject)
$object = $hashTable["custom"]
$object.customValue = 7
When I execute this code I get the following output.
test
Property 'customValue' cannot be found on this object; make sure it exists and is settable.
At C:\temp\test2.ps1:15 char:9
+ $object. <<<< customValue = 7
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : PropertyAssignmentException
Is there some way I can use the custom attribute after I've placed it into a collection?
I am using PowerShell 3.0 on 64-bit Windows 7. In 3.0 your code runs as expected, but in 2.0 (powershell.exe -Version 2.0) I get the same error as you. What's really strange is this output under 2.0:
PS> [Object]::ReferenceEquals($customObject, $object)
True
PS> $customObject | Get-Member
TypeName: System.Object
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
customValue NoteProperty System.String customValue=test
PS> $object | Get-Member
TypeName: System.Object
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
So, PowerShell agrees that they're the same object, yet only one has a customValue property. I also notice that if I change the way you are adding $customObject to $hashTable from this...
$hashTable.add("custom", $customObject)
...to this...
$hashTable["custom"] = $customObject
...then your code works as expected under PowerShell 2.0. So, it seems like something is going wrong in the call to Add(), and that behavior must have been fixed in 3.0.
Another workaround is to change the first line from this...
$customObject = New-Object object
...to this...
$customObject = New-Object PSObject
...and your code runs without error in both versions of PowerShell. You can then shorten the first two lines to this...
$customObject = New-Object PSObject -Property #{ customValue = "test" }