#html #powershell
#HTML #powershell
Вопрос:
Я новичок в Powershell и HTML. Я использую код Powershell в HTML-файле для отображения критериев истечения срока действия паролей AD и, наконец, отправки его по электронной почте. Генерируемое электронное письмо правильно отображает верхний и нижний колонтитулы, но средняя часть кода, которая запрашивает объявление, не показывает никаких строк в таблице HTML. Я подозреваю, что в моем использовании $body = что-то не так, но именно так предлагается в документации. Также, когда я индивидуально запускаю командлеты Powershell, я вижу, что возвращаются записи. Может кто-нибудь, пожалуйста, подсказать, где я могу ошибаться?
#Remove Digital Signature Check
Set-ExecutionPolicy Unrestricted
import-module activedirectory
# $ErrorActionPreference = 'SilentlyContinue'
$MailParams = @{
To = @("iq@mail.com")
From = "iq@mail.com"
Subject = "HTML Table"
SmtpServer = "mail.server.com"
}
try {
$body =
"<div>
<p>
<b><span >Attention IT Group:</span></b>
</p>
<BR>
</DIV>
<table border=0 cellspacing=0 cellpadding=0 width=94%>
<tbody>
<tr>
<td colspan=2 style='width:100.0%; border:solid #1F4E79 1.0pt; background:#1F4E79; padding:0cm 5.4pt 0cm 5.4pt'
<p >
<SPAN style='font-size:22.0pt; font-weight:bold; font-family:amp;quot;Arialamp;quot;,sans-serif; color:white'>
Password Expirations for Service Accounts
</SPAN>
</P>
</td>
</tr>"
# **** Need Code for Expire within < 1 Day ******
$body = Get-ADUser -Filter {Enabled -eq $True} -SearchBase "OU=Service Accounts,OU=SG1,OU=TAW,DC=wt,DC=ad,DC=cit,DC=com" `
-Properties * |
Sort-Object -Descending -Property @{Expression={($_.PasswordLastSet.AddDays(365) - [DateTime]::Now).Days}}|
# sort-object -Descending -property SamAccountName |
Where-Object{($_.PasswordLastSet.AddDays(365) - [DateTime]::Now).Days -le 1 }|
Select-Object -property `
@{Name="LogonName";Expression={$_.SamAccountName}} ,
@{Name="PasswordExpiration";Expression={$_.PasswordLastSet.AddDays(365).ToString("dd-MMM-yyyy")}} |
convertto-HTML -Fragment
# **** Need Code for Expire within 7 Days ( 2 - 7 Days) ******
$body = Get-ADUser -Filter {Enabled -eq $True} -SearchBase "OU=Service Accounts,OU=SG1,OU=TAW,DC=wt,DC=ad,DC=cit,DC=com" `
-Properties * |
Sort-Object -Descending -Property @{Expression={($_.PasswordLastSet.AddDays(365) - [DateTime]::Now).Days}}|
# sort-object -Descending -property SamAccountName |
Where-Object{($_.PasswordLastSet.AddDays(365) - [DateTime]::Now).Days -in (2,7) }|
Select-Object -property `
@{Name="LogonName";Expression={$_.SamAccountName}} ,
@{Name="PasswordExpiration";Expression={$_.PasswordLastSet.AddDays(365).ToString("dd-MMM-yyyy")}} |
convertto-HTML -Fragment
# **** Need Code for Expire within 7 Days ( 8 - 15 Days) ******
$body = Get-ADUser -Filter {Enabled -eq $True} -SearchBase "OU=Service Accounts,OU=SG1,OU=TAW,DC=wt,DC=ad,DC=cit,DC=com" `
-Properties * |
Sort-Object -Descending -Property @{Expression={($_.PasswordLastSet.AddDays(365) - [DateTime]::Now).Days}}|
# sort-object -Descending -property SamAccountName |
Where-Object{($_.PasswordLastSet.AddDays(365) - [DateTime]::Now).Days -in (8,15) }|
Select-Object -property `
@{Name="LogonName";Expression={$_.SamAccountName}} ,
@{Name="PasswordExpiration";Expression={$_.PasswordLastSet.AddDays(365).ToString("dd-MMM-yyyy")}} |
convertto-HTML -Fragment
# **** Need Code for Expire within 7 Days (16- 30 Days) ******
$body = Get-ADUser -Filter {Enabled -eq $True} -SearchBase "OU=Service Accounts,OU=SG1,OU=TAW,DC=wt,DC=ad,DC=cit,DC=com" `
-Properties * |
Sort-Object -Descending -Property @{Expression={($_.PasswordLastSet.AddDays(365) - [DateTime]::Now).Days}}|
# sort-object -Descending -property SamAccountName |
Where-Object{($_.PasswordLastSet.AddDays(365) - [DateTime]::Now).Days -in (16,30) }|
Select-Object -property `
@{Name="LogonName";Expression={$_.SamAccountName}} ,
@{Name="PasswordExpiration";Expression={$_.PasswordLastSet.AddDays(365).ToString("dd-MMM-yyyy")}} |
convertto-HTML -Fragment
#***** Footer of Email****
$body = " </tbody>
</table>
<BR>
<p style='margin-bottom:2.0pt'>
<span style='font-family:amp;quot;Calibriamp;quot;,sans-serif; color:black'> Management team<br> </span><span style='color:black'>
</span>
</p>
<BR>
"
$MailParams.body = $body
}
catch {
write-output "No records found for one of the criteria"
}
Send-MailMessage @MailParams -BodyAsHtml
Комментарии:
1.
ConvertTo-Html -Fragment
по-прежнему будет выводить автономный<table>
элемент, поэтому вы вкладываете новые<table>
элементы в тот, который у вас уже есть. Отображаются ли записи, если вы просматриваете необработанный HTML-код получаемого сообщения электронной почты?2. Это вызывает Get-ADUser 3x. Предлагаю разделить это по-другому. Извлеките данные один раз в коллекцию. Фильтр в три меньшие коллекции. Используйте эти коллекции для создания электронных писем. Кроме того, сделайте так, чтобы он работал как обычный текст, экспортируемый в CSV. Это позволит вам устранить неполадки с фильтрацией и тому подобное. Затем заставьте его экспортировать обычное текстовое электронное письмо в текстовый файл, что позволит устранить неполадки при создании электронного письма. Затем преобразуйте его в вывод html, чтобы вы могли устранить неполадки при генерации html. Другими словами, сначала добейтесь того, чтобы извлечение данных работало на 100%. Затем поэтапно повышайте сложность.
3. Xalorous, именно так мы подошли к этому, но требования пользователя изменились, поэтому нам пришлось добавить некоторую сложность в код. Матиас, записи появляются, если я проверяю необработанный вывод html, так почему же он не отображается в электронном письме? Спасибо вам обоим за ваши ценные предложения, надеюсь, я смогу решить эту проблему с помощью этого форума.
Ответ №1:
Это не будет полным ответом, и я в основном повторяю то, что люди уже сказали. Особенно комментарий, чтобы не вызывать Get-ADUser
три раза.
- Ваш
Get-Aduser
должен быть отфильтрован с помощью запроса — не возвращайте каждую включенную учетную запись, а затем используйтеWhere
предложение. Я предполагаю, что вам нужны учетные записи с последней установленной датой ввода пароля за 30 дней до того, какой будет 1-летняя годовщина даты ввода пароля? Возьмите все из них, а затем используйте своеWhere
предложение для результатов. - Отделите код, в котором вы создаете отчет о рекламе, от кода, в котором вы создаете HTML. И отделите это от кода, в котором вы создаете почтовое сообщение. В настоящее время у вас есть три разных процесса, соединенных вместе, и это усложняет устранение неполадок.
- Выводите свои фрагменты в виде HTML-файлов и тестируйте их по отдельности. Outlook действительно придирчив к отображаемому HTML
<div>
-коду и<span>
может стать драмой. Конечно, они работают в Outlook, но иногда какая-то комбинация не работает. Я стараюсь сделать это как можно проще.
Вот пример того, как может работать фильтр AD и последующая нарезка.
$1year = (get-date).AddDays(-365)
$30days = (get-date).AddDays(-334)
$tomorrow = (get-date).AddDays(-364)
$15days = (get-date).AddDays(-350)
# Get all the users that will be included in the report - one AD query
$users = get-aduser -filter 'passwordlastset -gt $1year -and passwordlastset -lt $30days -and enabled -eq "True"' `
-properties passwordlastset -searchbase "OU=myOU,DC=example,DC=com"
# break down the user list into the report categories
$expTomorrow = $users | where {$_.passwordLastSet -le $tomorrow} |
sort -Property passwordlastset -Descending |select -property `
@{Name="LogonName";Expression={$_.SamAccountName}},
@{Name="PasswordExpiration";Expression={$_.PasswordLastSet.AddDays(365).ToString("dd-MMM-yyyy")}}
$exp15Days = $users | where {$_.passwordLastSet -gt $tomorrow -and $_.passwordLastSet -le $15days} |
sort -Property passwordlastset -Descending | select -property `
@{Name="LogonName";Expression={$_.SamAccountName}},
@{Name="PasswordExpiration";Expression={$_.PasswordLastSet.AddDays(365).ToString("dd-MMM-yyyy")}}
$expOver15Days = $users | where {$_.passwordLastSet -gt $15days} |
sort -Property passwordlastset -Descending | select -property `
@{Name="LogonName";Expression={$_.SamAccountName}},
@{Name="PasswordExpiration";Expression={$_.PasswordLastSet.AddDays(365).ToString("dd-MMM-yyyy")}}
# assemble body
$preHTML = @'
...
'@
$postHTML = @'
...
'@
$body = $preHTML
$body = [fragment1]
$body = ...
# Send message
Send-MailMessage ...
Используя три набора пользователей для вашего отчета, вы можете проверить выходные данные каждого из них по отдельности, чтобы убедиться, что они выглядят правильно.
Для вашего тестирования выполните Convertto-HTML -fragment
несколько примеров коллекции, оберните их в действительно простой заголовок HTML, выведите в файл и посмотрите, как они выглядят в браузере.
Как только это будет выглядеть хорошо, создайте кодовый блок, чтобы собрать все тело в $body
переменную. Помните, что некоторые из этих пользовательских коллекций могут быть пустыми, поэтому вам нужно будет добавить $body
, чтобы в пустой коллекции не было ошибок (очевидно, проверьте это).
Я согласен с комментарием не переносить тело в еще одну таблицу. Просто создайте простой абзац со стилем текста для вашего заголовка. Не <span>
используйте теги, если вы на самом деле не стилизуете текст. Еще раз проверьте, как он отображается в браузере при выводе в виде простого HTML-файла.
Тогда ваш Send-MailMessage
может быть в своем собственном кодовом блоке. Это позволяет намного легче увидеть, где что-то идет не так.