haru777999
Goto Top

Benötige Hilfe in der Exchange Shell: Zwei Arrays und mit dem ersten prüfen, ob es im zweiten vorhanden ist

Hallo zusammen

Also, ich lege zwei Arrays in der Exchange Shell wie folgt an (MS Exchange Server 2010):
[array]$accdoms = @(Get-AcceptedDomain | select DomainName | sort DomainName | ft -HideTableHeaders)
[array]$smtpadr = @(Get-Mailbox | select PrimarySMTPAddress | sort PrimarySMTPAddress | ft -HideTableHeaders)
Das erste Array $accdoms sieht gekürzt so aus und enthält alle accepted Mail-Domains:
abc.ch
def.ch
uvw-xyz.ch
Das zweite Array $smtpadr sieht gekürzt so aus und enthält alle Mail Adressen (PrimarySMTPAddress):
uhu@abc.ch
eule@abc.ch
audi@def.ch
fiat@def.ch
opel@def.ch
saab@def.ch
mars@uvw-xyz.ch
merkur@uvw-xyz.ch
Jetzt möchte ich mit dem ersten Element aus dem ersten Array (quasi $accdoms) prüfen, ob es Mail-Adressen mit dieser Domain (z.B. def.ch) im zweiten Array gibt.
Diese Mail-Adressen sollen grad in ein File geschrieben werden, welches def.ch.txt heissen soll. Je Domain ein File mit dem Domainnamen.txt.
Dabei sollen nur die Mail-Adressen vom Typ "User Mailbox" verarbeitet werden. Leider ist die "DistributionSearchMailbox" auch im zweiten Array drin.
Alles klar?

Was ich u.v.a. versucht habe:
ForEach ($dom in $accdoms) { Get-Mailbox | Where {$_.PrimarySMTPAddress -match "$dom"} | select Name, PrimarySMTPAddress | ft -HideTableHeaders }  

Vielen Dank im Voraus!

Grüsse
Haru

Content-Key: 256548

Url: https://administrator.de/contentid/256548

Ausgedruckt am: 28.03.2024 um 23:03 Uhr

Mitglied: ITvortex
ITvortex 03.12.2014 um 17:00:06 Uhr
Goto Top
Hallo,

soweit so gut, und wieso dann in der ForEach Get-Mailbox?
Du willst das erste Element, wie du schon richtig gesagt hast $accdoms, mit jedem Element, $smtpadr[i], vergleichen?
Davon lese ich hier allerdings nicht. Falls ich was übersehen habe ist schon ein langer Tag face-smile

Liebe Grüße
ITvortex
Mitglied: colinardo
colinardo 03.12.2014, aktualisiert am 04.12.2014 um 18:21:43 Uhr
Goto Top
Hallo Haru,
kein Problem:
$accdoms = Get-AcceptedDomain | select -Expand DomainName | select -Expand Address
$smtpadr = Get-Mailbox | ?{$_.PrimarySmtpAddress -notmatch '[\{\}]'} | select PrimarySmtpAddress  
$accdoms | %{$dom = $_; $smtpadr | ?{$_.PrimarySmtpAddress.Domain -eq $dom} | %{$_.PrimarySmtpAddress.toString()} | set-content "$dom.txt"}  
andere Methode
$accdoms = Get-AcceptedDomain | select -Expand DomainName | select -Expand Address
$groups = Get-Mailbox | ?{$_.PrimarySmtpAddress -notmatch '[\{\}]'} | select -ExpandProperty PrimarySmtpAddress | group Domain  
$groups | ?{$accdoms -contains $_.Name} | %{$_.Group | set-content "$($_.Name).txt"}   
Grüße Uwe

p.s. was mir bei deinem Codestil aufgefallen ist, ist das Speichern von Daten als pure Strings mit den Format-CMDLEts(format-table, etc.) in den Variablen. Dies bitte in Zukunft unbedingt vermeiden! Normalerweise verwendet man die Format-CMDLets wirklich nur zur Ausgabe in Dateien oder ähnlichem, nicht zum vergleichen etc. Man behält die Daten normalerweise so lange wie möglich als Objekte (ganz wichtige Powershell-Regel face-wink).

-edit- 04.12.2014 18:21 - Code aktualisiert.
Mitglied: Haru777999
Haru777999 04.12.2014 aktualisiert um 09:31:43 Uhr
Goto Top
Hallo ITvortex

Ja genau, Du hast es richtig verstanden.
Weiter so.
Das foreach kommt halt von der Programmierung mit anderen Sprachen.
Tue mich als Beginner seeeehr schwer mit der PS.

Danke und Gruss
Haru
Mitglied: Haru777999
Haru777999 04.12.2014 aktualisiert um 09:59:44 Uhr
Goto Top
Hallo Uwe

Besten Dank für Deine Antwort.

Dein 1. Ansatz:
Bemerkungen dazu: Im Array $accdoms habe ich mehrere Zeilen pro Domain. Im Array $smtpadr gibt es keine @. In Zeile 3 ist ein ; (%{$dom = $_;$smtpadr). Geht das? Muss es nicht ein . sein?
Die Meldung von PS beim Ausführen der 3. Zeile lautet:
Method invocation failed because [Microsoft.Exchange.Data.SmtpAddress] doesn't contain a method named 'Split'.  
At line:1 char:45
+ $accdoms | %{$dom = $_;$smtpadr | ?{$_.Split <<<< ("@")[1] -eq $dom} | out-file "$dom.txt"}  
    + CategoryInfo          : InvalidOperation: (Split:String) , RuntimeException
    + FullyQualifiedErrorId : MethodNotFound
Es wird ein einziges leeres File erstellt mit dem Namen abc.local.txt.

Dein 2. Ansatz:
Läuft nur ganz kurz und schreibt leider nichts.

Hier noch meine PS Version:
[PS] C:\temp>$PSVersionTable
CLRVersion                     2.0.50727.5485
BuildVersion                   6.1.7601.17514
PSVersion                      2.0
WSManStackVersion              2.0
PSCompatibleVersions           {1.0, 2.0}
SerializationVersion           1.1.0.1
PSRemotingProtocolVersion      2.1

Wie weiter?
Grüsse
Haru
Mitglied: colinardo
colinardo 04.12.2014 aktualisiert um 18:28:22 Uhr
Goto Top
Hallo Haru,
liegt an deiner verwendeten alten PS Version face-wink Version 3.0 sollte es inzwischen schon sein ... , ist für mich als alten PS Hasen halt schon selbstverständlich, denke ich leider nicht immer dran face-wink
Das hier sollte auch mit PS 2.0 laufen:
$accdoms = Get-AcceptedDomain | select -ExpandProperty DomainName
$smtpadr = Get-Mailbox -ResultSize unlimited | ?{$_.PrimarySmtpAddress -notmatch '[\{\}]'} | select -ExpandProperty PrimarySmtpAddress  
$accdoms | %{$dom = $_;$smtpadr | ?{$_.toString().Split("@")[1] -eq $dom} | set-content "$dom.txt"}  

In Zeile 3 ist ein ; (%{$dom = $_;$smtpadr). Geht das? Muss es nicht ein . sein?
Nein, das ist schon richtig so face-smile das Semikolon trennt einfach die Zeile von einer neuen ohne einen Zeilenumbruch zu machen.

Alles wird gut.
Grüße Uwe
Mitglied: Haru777999
Haru777999 04.12.2014 um 16:32:25 Uhr
Goto Top
Hey Uwe,
IMHO habe ich für das $smtpaddr in Zeile 02. "-ExpandProperty" weggenommen. So kommt nur noch die PrimarySMTPAddress und die hat ja @.
Vorher kamen die Spalten "Length, Local, Domain und IsValidAddress", aber ohne @.

Resultat: Die Files werden alle geschrieben, sind aber noch leer.
Scheint ein grosser Unterschied in den PS Versionen zu sein, aber ich darf in dieser Firma gar nichts updaten, schon gar nicht auf die Schnelle.

Wie weiter? Danke im Voraus.
Grüsse
Haru
Mitglied: colinardo
Lösung colinardo 04.12.2014, aktualisiert am 05.12.2014 um 09:01:25 Uhr
Goto Top
Ahh jetzt ich seh das Problem bei euch ... die kleinen Unterschiede zwischen den PS-Versionen nerven manchmal echt, sorry für die Umstände face-wink Asche auf mein Haupt)
$accdoms = Get-AcceptedDomain | select -Expand DomainName | select -Expand Address
$smtpadr = Get-Mailbox | ?{$_.PrimarySmtpAddress -notmatch '[\{\}]'} | select PrimarySmtpAddress  
$accdoms | %{$dom = $_; $smtpadr | ?{$_.PrimarySmtpAddress.Domain -eq $dom} | %{$_.PrimarySmtpAddress.toString()} | set-content "$dom.txt"}  
und für die andere Variante siehts dann so aus:
$accdoms = Get-AcceptedDomain | select -Expand DomainName | select -Expand Address
$groups = Get-Mailbox | ?{$_.PrimarySmtpAddress -notmatch '[\{\}]'} | select -ExpandProperty PrimarySmtpAddress | group Domain  
$groups | ?{$accdoms -contains $_.Name} | %{set-content "$($_.Name).txt" -Value $_.Group}   
Grüße Uwe
Mitglied: Haru777999
Haru777999 05.12.2014 um 09:01:22 Uhr
Goto Top
Hey Uwe
Herzlichen Dank! Beide Varianten tun perfekt!
Man liest sich.
Grüsse
Haru
Mitglied: Haru777999
Haru777999 17.12.2014 aktualisiert um 15:20:55 Uhr
Goto Top
Hey Uwe

Ich möchte PS gerne auch ein bisschen beherrschen, aber keine Chance.
Verbrate aber leider nur seeeehr viel Zeit. Mit keiner anderen Programmiersprache habe ich mich so schwer getan.
Nun, in der 6. Zeile (3. Zeile in Deiner Variante) möchte ich dem Value $_.Group (ist die PrimarySMTPAddress) noch ein Gleichheitszeichen vorsetzen, in etwa so: =uhu@abc.ch
$mailhost = gc env:computername;
$equsign = "="  
if ($mailhost -ieq "MAIL01") {  
	$accdoms = Get-AcceptedDomain | select -Expand DomainName | select -Expand Address;
	$mgroups = Get-Mailbox | ?{$_.RecipientTypeDetails -ieq "UserMailbox" -and $_.IsMailboxEnabled -ieq "True"} | select -ExpandProperty PrimarySmtpAddress | sort $_.PrimarySMTPAddress | group Domain | sort Name;  
    $mgroups | ?{$accdoms -contains $_.Name} | %{set-content "C:\Temp\zepo\$($_.Name).txt" -Value $eqsign + $_.Group};  
}

In den Textfiles steht jetzt nur eine Zeile: + Microsoft.PowerShell.Commands.GroupInfo.Group

Geht einfach nicht. Kann gar nichts dort dazwischen setzen, auch nicht "-Value + "=" + $_.Group" oder -Value =$_.Group.
Nochmals vielen Dank.
Haru
Mitglied: colinardo
Lösung colinardo 17.12.2014 aktualisiert um 15:58:15 Uhr
Goto Top
Hallo Haru,
du musst dich bei sowas schrittweise auf der Shell herantasten und dir den Inhalt von $_.Group anzeigen lassen, dann siehst du das es ein Array aus Objekten ist welches natürlich auch als solches behandelt werden will.
So wie deine Beschreibung klingt möchtest du vor jede E-Mail-Adresse ein Gleichheitszeichen setzen. In diesem Fall machst du das so:
$mgroups | ?{$accdoms -contains $_.Name} | %{set-content "C:\Temp\zepo\$($_.Name).txt" -Value ($_.Group | %{"=$_"})}
Du musst also das Array erst auflösen bzw. über jeden Wert mit einer For-Each-Schleife itterieren %{} und entsprechend mit dem Gleichheitszeichen ausgeben ($_.Group | %{"=$_"})
Das $_ repräsentiert dabei bei jedem Schleifendurchlauf den Wert der aktuellen Zeile des Arrays. Das ganze wird in den normalen Klammern erst aufgelöst, und dann an den -Value Parameter übergeben.

Grüße Uwe
Mitglied: Haru777999
Haru777999 17.12.2014 aktualisiert um 16:13:57 Uhr
Goto Top
Uwe, vielen Dank, es tut!
Ist ja noch kryptischer als Perl...
Grüsse
Haru