Мне нужно написать сценарий, который отправляет одно электронное письмо каждому человеку. Это электронное письмо будет иметь уникальные коды для человека. Каждый человек может получить любое количество кодов.
Данные выглядят так
Email,Codes
[email protected],213
[email protected],999
[email protected],111
[email protected],123
[email protected],643
[email protected],809
[email protected],722
[email protected],013
Я думаю, сценарий будет примерно таким.
#get the data
$PeopleAndCodes = Import-Csv C:\temp\PeopleCodes.csv
#Count how many groups of unique people
[array]$CountOfPeople = $PeopleAndCodes.email | Group-Object -noelement | Select-Object Count
#Loop through unique people
$Index = 0;
while ($Index -lt $CountOfPeople.count) {
$Index++
#THIS BELOW EXITS BEFORE GETTING THROUGH ALL THE CODES FOR ONE PERSON
[int]$DCodes = 0
foreach ($DCodes in [int]$CountOfPeople[$DCodes].count) {
$DCodes++
Write-Host $DCodes DCODES
Write-Host $CountOfPeople[$DCodes].count CountOfPeople
Write-Host $PeopleAndCodes[$DCodes].codes
}
}
Проблема в том, что мой второй цикл останавливается, как только достигается количество уникальных людей, а затем переходит к следующему человеку.
Я не понимаю, почему 2-й цикл не проходит по кодам, а затем к следующему человеку?
Вы очень близки, я бы внес небольшие изменения в ваш код, и мы сможем получить его там.
Во-первых, вместо того, чтобы индексировать массив, давайте выберем все уникальные электронные письма из списка кодов.
$uniqueUsers = $PeopleAndCodes | select -Unique Email
Затем мы можем foreach
пройтись по списку $uniqueUsers
и для каждого найти подходящие коды.
foreach($uniqueUser in $uniqueUsers){
$thisEmail = $uniqueUser.Email
$matchingCodes = $PeopleAndCodes | Where Email -Match $uniqueUser.Email |
Select-Object -ExpandProperty Codes
Теперь у нас есть в этом цикле переменная $thisEmail
, которая содержит адрес электронной почты пользователя, а затем массив всех совпадающих кодов для пользователя, называемый $matchingCodes
. Нам также не нужно индексировать их. На самом деле вторая петля, скорее всего, была причиной проблемы, так как в списке больше элементов, чем уникальных пользователей.
Условием ограничения было количество уникальных пользователей, а не количество элементов в списке..
Итак, чтобы избежать путаницы и получить желаемый результат, просто полностью удалите этот второй цикл, поскольку он нам не помогает.
Write-Host "Person - $thisEmail"
Write-Host "Person has $($matchingCodes.Count) codes"
$matchingCodes -join ","
Дает вывод
Person - [email protected]
Person has 2 codes
213,999
--------------------
Person - [email protected]
Person has 5 codes
111,123,643,809,722
$PeopleAndCodes = Import-Csv C:\temp\PeopleCodes.csv
$uniqueUsers = $PeopleAndCodes | select -Unique Email
foreach($uniqueUser in $uniqueUsers){
$thisEmail = $uniqueUser.Email
$matchingCodes = $PeopleAndCodes | where Email -Match $uniqueUser.Email | Select-Object -ExpandProperty Codes
Write-Host "Person - $thisEmail"
Write-Host "Person has $($matchingCodes.Count) codes"
$matchingCodes -join ","
Write-Host "--------------------"
}
Я хочу отметить, что пока это лучший ответ. В комментариях есть еще один ответ, который также работает с моим исходным кодом.
#get the data
$PeopleAndCodes = Import-Csv C:\temp\PeopleCodes.csv
#Count how many groups of unique people
[array]$CountOfPeople = $PeopleAndCodes.email | Group-Object -noelement | Select-Object Count
#Loop through unique people
$Index = 0;
while ($Index -lt $CountOfPeople.count) {
$Index++
#This loops through each person and gets their code(s)
[int]$DCodes = 0
foreach ($DCodes in 0..[int]$CountOfPeople[$DCodes].count) {
Write-Host $PeopleAndCodes[$DCodes].email
Write-Host $PeopleAndCodes[$DCodes].codes
$DCodes++
}
}
Я верю в ваш внутренний цикл
foreach
, который вы хотели использовать0..[int]$CountOfPeople[$DCodes].count
, хотя код кажется сложным и, вероятно, может быть проще