h41msh1c0r
Goto Top

Powershell Hashtable Key False

Aloa,

Hashtable
$alldata

Name                           Value                                                                         
----                           -----                                                                         
@{serviceName=TRAINING {Count, Status, Ordered, Modified...}                                         
@{serviceName=TRN {Count, Status, Ordered, Modified...}                                         
@{serviceName=ad_test {Count, Status, Ordered, Modified...}

Jetzt wird gesucht ob "ad_test" vorhanden ist:

$alldata.ContainsKey("ad_test")  

--> False

$alldata.Keys | %{

    write-host $_.serviceName

    if ($_.serviceName -like "ad_test"){  
        write-host "enthält"  
    }else{
        write-host "enthält NICHT"  
    }
}
Wenn ich aber die Keys durchlaufe findet er ihn natürlich.

Warum liefert ContainsKey ein False?

VG

Content-ID: 667951

Url: https://administrator.de/forum/powershell-hashtable-key-false-667951.html

Ausgedruckt am: 26.12.2024 um 15:12 Uhr

Dani
Dani 06.09.2024 um 18:50:35 Uhr
Goto Top
Moin,
möchtest du noch den Code posten, mit dem du die Variable $alldata erzeugt hast?


Gruß,
Dani
14260433693
Lösung 14260433693 06.09.2024 aktualisiert um 21:09:42 Uhr
Goto Top
Warum liefert ContainsKey ein False?
Weil deine Keys in sich selbst schon
Hashtables sind und keine Strings, denn der String den du suchst ist in der Key-Hashtable unter "ServiceName" verzeichnet...sieht man ja schon am ersten Beispiel deiner Ausgabe.
Du hast unnötigerweise doppelt gemoppelt verschachtelt.
aqui
aqui 07.09.2024 um 09:24:58 Uhr
Goto Top
14260433693
14260433693 07.09.2024 aktualisiert um 10:33:41 Uhr
Goto Top

Da gab es noch einen der das mal so auf sein Cover gepresst hat 😂. Die billige Kopie von Freddy Quinn
https://www.discogs.com/de/release/1183730-Freddy-Breck-Halli-Hallo-Aloa ...
aqui
aqui 07.09.2024 aktualisiert um 18:26:52 Uhr
Goto Top
Oha, der sieht auch nicht so aus als ob er jemals auf Hawaii war und "Aloha" gesagt hat! 🤣
H41mSh1C0R
H41mSh1C0R 09.09.2024 um 08:51:28 Uhr
Goto Top
Zitat von @14260433693:

Warum liefert ContainsKey ein False?
Weil deine Keys in sich selbst schon
Hashtables sind und keine Strings, denn der String den du suchst ist in der Key-Hashtable unter "ServiceName" verzeichnet...sieht man ja schon am ersten Beispiel deiner Ausgabe.
Du hast unnötigerweise doppelt gemoppelt verschachtelt.

Moin,
Leuchtet ein.
Dann schau ich mal wie ich an den ServiceName in der Hashtable komme.
VG
H41mSh1C0R
H41mSh1C0R 09.09.2024 um 08:54:51 Uhr
Goto Top
Zitat von @Dani:

Moin,
möchtest du noch den Code posten, mit dem du die Variable $alldata erzeugt hast?


Gruß,
Dani

Powershell New-Object meckert Property an, Verständnisfrage

In AllData sind Hashtables drin deren Values ich im nächsten Schritt befüllen möchte. Von jedem Service gibt es xyz Anzahlen an Instanzen und in AllData werden dann die Counter hochgezählt. Nach Aktion, Status und Jahr. So der Plan.
14260433693
14260433693 09.09.2024 aktualisiert um 09:14:47 Uhr
Goto Top
Zitat von @H41mSh1C0R:

Zitat von @Dani:

Moin,
möchtest du noch den Code posten, mit dem du die Variable $alldata erzeugt hast?


Gruß,
Dani

Powershell New-Object meckert Property an, Verständnisfrage

In AllData sind Hashtables drin deren Values ich im nächsten Schritt befüllen möchte. Von jedem Service gibt es xyz Anzahlen an Instanzen und in AllData werden dann die Counter hochgezählt. Nach Aktion, Status und Jahr. So der Plan.

Dann hast du es aber nicht so aufgebaut wie ich es gepostet habe denn damit geht es ja problemlos weil die Keys selbst ja normale Strings sind.
Guckst du

https://tio.run/##dVFBC4IwGL3vV4whWBCRVqcQDI8RHTxGh@W@aCCbbLMI8bfbzFxatN ...

Wenn du als Key selbst Hashtables verwendest dann bleibt dir nur das Filtern mit Where-Object, aber ich denke du hast da nur einen Umsetzungsfehler gemacht ...
H41mSh1C0R
H41mSh1C0R 09.09.2024 um 09:32:04 Uhr
Goto Top
$alldata.ContainsKey('ad_test') bleibt bei mir leer.

Den einzigen Unterschied den ich sehe ist wie ich die Variable $ServiceOfferingsListe befülle.
$years           = @{"2020"='';"2021"='';"2022"='';"2023"='';"2024"='';"2025"=''}    
#$ServiceOfferingsListe =("Subscription1","Subscription2","Subscription3" ) 

$ServiceOfferingsListe = $SubscriptionDetails | select servicename -Unique

$Status          = @{"Active"='';"Cancelled"=''}     
$alldata         = @{}

foreach ($ServiceOffering in $ServiceOfferingsListe){
    $alldata.$ServiceOffering = [ordered]@{
        Count=''    
        Status=$Status
        Ordered=$years
        Modified=$years
        Cancelled=$years
    }
}

Kann das vielleicht daran liegen das ich mir die ServiceNamen aus einer Objektliste hole?

$ServiceOfferingsListe = $SubscriptionDetails | select servicename -Unique

Ergebnis:
PS C:\Users\user> $ServiceOfferingsListe

servicename                                                
-----------                                                
TRAINING
TRN
ad_test

Also nur weil das hier alles einzeln steht sind das quasi alles Objekte die nur servicename als Property haben.
Diese Liste in ein Array aus Strings umbauen und dann klappt das auch mit dem foreach?

Aus jeder Subscription hole ich mir folgende Dinge und die stehen dann in einem PSCustomObject:

id               : 8a2ea6097aead510017b2ecfcc2820f7
owner            : User
serviceName      : ad_test
name             : ad_test (0.3.44)
subscriptionTerm : @{startDate=2021-08-10T06:46:03.000Z}
status           : CANCELLED
instanceState    : CANCELLED
offeringVersion  : 0.3.44
history          : {@{id=8a2ea6097b7af4d2017c30e25231160f; date=2021-09-29T09:28:31.025Z; status=SUCCESS; 
                   type=Request; title=Cancel Subscription; actionError=; requestedAction=CANCEL_SUBSCRIPTION}, 
                   @{id=8a2ea6097aead510017b2ecf8bd11f23; date=2021-08-10T06:45:58.865Z; status=FAILURE; type=Request; 
                   title=Order; actionError=12.08.2021 09:05:33: 
                   ; requestedAction=ORDER}}

Mach ich jetzt auf ServiceOfferingsListe ein Get-Member bekomme ich 2 Ausgaben:

TypeName: Selected.System.Collections.Hashtable

Name        MemberType   Definition                    
----        ----------   ----------                    
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()             
GetType     Method       type GetType()                
ToString    Method       string ToString()             
servicename NoteProperty object servicename=null       


   TypeName: Selected.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()                         
serviceName NoteProperty string serviceName=ad_test

Aber selbst mit einem Where-Object bleibt die Ausgabe leer.

$alldata | Where-Object -property serviceName -eq "ad_test"  
14260433693
Lösung 14260433693 09.09.2024 aktualisiert um 09:49:52 Uhr
Goto Top
Ändere die Zeile so, dann klappt das auch
$ServiceOfferingsListe = $SubscriptionDetails | select -ExpandProperty servicename -Unique
Weil die Variable dann keine Properties mehr hat ...

Alternativ kannst du aber auch das hier in der Schleife schreiben wenn du Servicename vorher nicht expandieren willst
# ...
   $alldata.($ServiceOffering.ServiceName) = [ordered]@{
        Count=''      
        Status=$Status
        Ordered=$years
        Modified=$years
        Cancelled=$years
    }
# ...
H41mSh1C0R
H41mSh1C0R 09.09.2024 um 09:48:11 Uhr
Goto Top
$ServiceOfferingsListeTemp = $SubscriptionDetails | select servicename -Unique

$result = @()

$ServiceOfferingsListeTemp | %{
    $result += "$($_.servicename)"  
}

$ServiceOfferingsListe = $result

$years           = @{"2020"='';"2021"='';"2022"='';"2023"='';"2024"='';"2025"=''}    
$Status          = @{"Active"='';"Cancelled"=''}     
$alldata         = @{}

foreach ($ServiceOffering in $ServiceOfferingsListe){
    $alldata.$ServiceOffering = [ordered]@{
        Count=''    
        Status=$Status
        Ordered=$years
        Modified=$years
        Cancelled=$years
    }
}
$alldata."ad_test"  

Keine Schönheit aber funktioniert. =)

$alldata."ad_test"  

Name                           Value                                                                                   
----                           -----                                                                                   
Count                                                                                                                  
Status                         {Active, Cancelled}                                                                     
Ordered                        {2020, 2024, 2025, 2021...}                                                             
Modified                       {2020, 2024, 2025, 2021...}                                                             
Cancelled                      {2020, 2024, 2025, 2021...}                                                             
H41mSh1C0R
H41mSh1C0R 09.09.2024 aktualisiert um 09:56:24 Uhr
Goto Top
Zitat von @14260433693:

Ändere die Zeile so, dann klappt das auch
$ServiceOfferingsListe = $SubscriptionDetails | select -ExpandProperty servicename -Unique
Weil die Variable dann keine Properties mehr hat ...

Alternativ kannst du aber auch das in der Schleife schreiben wenn du Servicename vorher nicht expandieren willst
# ...
   $alldata.($ServiceOffering.ServiceName) = [ordered]@{
        Count=''      
        Status=$Status
        Ordered=$years
        Modified=$years
        Cancelled=$years
    }
# ...

So bekomme ich das mit einem Fehler quittiert:

PS C:\Users\user> $SubscriptionDetails | Select-Object -ExpandProperty serviceName -Unique
Select-Object : Property "serviceName" cannot be found.  
At line:1 char:24
+ ... bscriptionDetails | Select-Object -ExpandProperty serviceName -Unique
+                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (System.Collections.Hashtable:PSObject) [Select-Object], PSArgumentExce 
   ption
    + FullyQualifiedErrorId : ExpandPropertyNotFound,Microsoft.PowerShell.Commands.SelectObjectCommand
 
TRAINING
TRN
ad_test
DB_USER_HOBBY_TM
SQL_USER_HOBBY_TM

Also er gibt nach der Fehlermeldung die Liste schon aus, nur halt mit Fehler davor.
14260433693
14260433693 09.09.2024 aktualisiert um 09:58:46 Uhr
Goto Top
Property "serviceName" cannot be found.
Dann dürfte deine Zeile auch schon nicht funktionieren wenn es die Property im Objekt nicht gibt. Wir kennen das Ausgangsobjekt SubscriptionDetails nicht ... Wenn das keine Property serviceName hat klappt das verständlicherweise nicht.
H41mSh1C0R
H41mSh1C0R 09.09.2024 um 09:59:04 Uhr
Goto Top
läuft auch, dankööö. =)
H41mSh1C0R
H41mSh1C0R 09.09.2024 aktualisiert um 10:04:54 Uhr
Goto Top
Zitat von @14260433693:

Property "serviceName" cannot be found.
Dann dürfte deine Zeile auch schon nicht funktionieren wenn es die Property im Objekt nicht gibt. Wir kennen das Ausgangsobjekt SubscriptionDetails nicht ... Wenn das keine Property serviceName hat klappt das verständlicherweise nicht.

Doch "serviceName" gibt es.

id               : 8a2ea6097aead510017b2ecfcc2820f7
owner            : User
serviceName      : ad_test
name             : ad_test (0.3.44)
subscriptionTerm : @{startDate=2021-08-10T06:46:03.000Z}
status           : CANCELLED
instanceState    : CANCELLED
offeringVersion  : 0.3.44
history          : {@{id=8a2ea6097b7af4d2017c30e25231160f; date=2021-09-29T09:28:31.025Z; status=SUCCESS; 
                   type=Request; title=Cancel Subscription; actionError=; requestedAction=CANCEL_SUBSCRIPTION}, 
                   @{id=8a2ea6097aead510017b2ecf8bd11f23; date=2021-08-10T06:45:58.865Z; status=FAILURE; type=Request; 
                   title=Order; actionError=12.08.2021 09:05:33: 
                   ; requestedAction=ORDER}}

Aber ich hab das jetzt so angepasst wie du oben geschrieben hast und das passt:

# ...
   $alldata.($ServiceOffering.ServiceName) = [ordered]@{
        Count=''        
        Status=$Status
        Ordered=$years
        Modified=$years
        Cancelled=$years
    }
# ...
14260433693
Lösung 14260433693 09.09.2024 aktualisiert um 10:08:48 Uhr
Goto Top
Wenn die Variable ne Hashtable ist und kein Custom-Object dann ist das klar dann hat das auch keine Property servicename sondern nur nen Key mit dem Namen ...

Immer dran Denken mit welchen Typen du arbeitest. => Get-Member und .gettype() sind deine Freunde.

Du siehst den Unterschied:
#Hashtable mit Fehler weil keine Property mit dem Namen  ...
@{serviceName = "AB"} | select -Expand serviceName  
# Object mit Property
[pscustomobject]@{serviceName = "AB"} | select -Expand serviceName  
H41mSh1C0R
H41mSh1C0R 09.09.2024 um 10:15:25 Uhr
Goto Top
Danke für die Erklärungen. Nächster Zettel am Bildschirmrand worauf geachtet werden muss.
face-smile