Powershell,Excel在单元格中查找string,颜色行,删除其他

那么我正在寻找一种方法来阅读我的Excel表格。

  1. find空单元格,并给他们一个名字,然后标记为黄色。
  2. 查找包含一定字的行,并将其标记为红色。 如果脚本
  3. 如果找不到行中指定的单词,则应删除整行。

这是我的脚本到目前为止: 任何帮助将不胜感激

在@TheMadTechician的帮助下更新

#If there is no Out-Clipboard, set it If(!(Get-Command Out-Clipboard -ErrorAction SilentlyContinue)){Set-Alias Out-Clipboard "$env:SYSTEMROOT\System32\clip.exe"} #Get current date $Date = get-date -format yyyy-MM-dd $Company = "company" $Company2 = "company2" #Define all files/Paths. $Path = "C:\$Company2\BlockedIP" md "$Path\HTML\$Date" -Force |Out-Null $path2 = "$Path\HTML\$Date" $PathWeb = "/HTML/$Date" #Path = C:/$Company2/BlockedIP #Path2 = C:/$Company2/BlockedIP/HTML/2014-07-09 #Define File's used or created in this script. $File = "$Path\IP-$Date.txt" $FileHtml = "$Path2\IP-$Date.htm" $FileXML = "$Path\IP-$Date.xlsx" $FileHTMLWeb = "$PathWeb\IP-$date.htm" #File = C:/$Company2/BlockedIP/IP-2014-07-09.txt #FileXML = C:/$Company2/BlockedIP/HTML/2014-07-09/IP-2014-07-09.htm #FileHtml = C:/$Company2/BlockedIP/HTML/2014-07-09/IP-2014-07-09.xlsx #FileHTMLWeb = PublicIP/HTML/2014-07-09/IP-2014-07-09.htm #Define error actions. #$erroractionpreference = "SilentlyContinue" #Get content from given IP list. $colComputers = @(get-content $File | Sort -unique) $count = $colComputers.Count write-output "$Count IP's detected." #Get DNS Results $Progress=1 $DNSResults = $colComputers | %{ Write-Progress -Activity "Creating a usable 'Blocked IP' list ($Progress/$count)" -PercentComplete ($Progress/$Count*100) -Status "Please stand by" try { ($dnsresult = [System.Net.DNS]::GetHostEntry($_))|out-null } catch { $dnsresult = "Fail" } [PSCustomObject][Ordered]@{ Source=$_.ToUpper() HostName=$dnsresult.HostName IPAddress=$dnsresult.AddressList[0].ToString() } $Progress++ } $DNSResults | Sort HostName | ConvertTo-Csv -Delimiter "`t" -NoTypeInformation | Select -Skip 1 | Out-Clipboard #Open Excel. $a = New-Object -comobject Excel.Application #Since we want this script to look like it's being used without excel I set it's visibility to false. $a.visible = $True #Disable excel confirmations. $a.DisplayAlerts = $False <# # set interactive to false so nothing from excel is shown. $Excel.DisplayAlerts = $false $Excel.ScreenUpdating = $false $Excel.Visible = $false $Excel.UserControl = $false $Excel.Interactive = $false #> #Create sheets in Excel. $b = $a.Workbooks.Add() $c = $b.Worksheets.Item(1) $c.Activate() | Out-Null #Create a Title for the first worksheet and adjust the font $c.Cells.Item(1,1)= "Blocked IP's $Date" $c.Cells.Item(1,1).Font.ColorIndex = 55 $c.Cells.Item(1,1).Font.Color = 8210719 $range = $c.Range("a1","e1") $range.Style = 'Title' $range.Select() $range.MergeCells = $true $range.VerticalAlignment = -4108 $CounterRow = $Count+5 #Define subjects. $c.Name = "Blocked IP's ($Date)" $c.Cells.Item(2,1) = "Given IP" $c.Cells.Item(2,2) = "Resolved DNS" $c.Cells.Item(2,3) = "Returned IP" $c.Cells.Item(2,5) = "$Company" $c.Cells.Item($Count+5,1) = "Created by" $link = "http://www.$Company" $link2 = "https://www.linkedin.com/profile/view?id=#########" $r = $c.Range("E2") [void]$c.Hyperlinks.Add($r, $link) $r = $c.Range("A$Counterrow") [void]$c.Hyperlinks.Add($r, $link) #Define cell formatting from subjects. $c.Range("A2:E2").Interior.ColorIndex = 6 $c.Range("A2:E2").font.size = 13 $c.Range("A2:E2").Font.ColorIndex = 1 $c.Range("A2:E2").Font.Bold = $True #Define html code for Excel save to .htm. $xlExcelHTML = 44 #Define the usedrange, excluding header and footer rows $e = $c.Range("A3:E$($DNSResults.Count+2)") #Populate data into spreadsheet $DNSResults | Sort HostName | ConvertTo-Csv -Delimiter "`t" -NoTypeInformation | Select -Skip 1 | Out-Clipboard #$c.Cells.Item(3,1).Select() $c.Paste($e,$false) $e = $c.Range("A3:C$($DNSResults.Count+2)") $c.Paste($e,$false) $Keywords = "Google","thenetworkfactory","HappyTreeFriends" $Filter = "($(($Keywords|%{[RegEx]::Escape($_)}) -join "|"))" $DNSResults | Where{$_ -match $filter} | Sort HostName | ConvertTo-Csv -Delimiter "`t" -NoTypeInformation | Select -Skip 1 | Out-Clipboard ForEach($Cell in $e){ If([String]::IsNullOrWhitespace($Cell.value2)){$Cell.interior.colorindex=6} } #Define the usedrange for autofitting. $d = $c.UsedRange #Set background color for the IP list. $E.interior.colorindex = 15 #Define borders here. $xlOpenXMLWorkbook = 51 $xlAutomatic=-4105 $xlBottom = -4107 $xlCenter = -4108 $xlRight = -4152 $xlContext = -5002 $xlContinuous=1 $xlDiagonalDown=5 $xlDiagonalUp=6 $xlEdgeBottom=9 $xlEdgeLeft=7 $xlEdgeRight=10 $xlEdgeTop=8 $xlInsideHorizontal=12 $xlInsideVertical=11 $xlNone=-4142 $xlThin=2 $selection = $c.range("A3:C$($DNSResults.Count+2)") $selection.select() |out-null $selection.HorizontalAlignment = $xlRight $selection.VerticalAlignment = $xlBottom $selection.WrapText = $false $selection.Orientation = 0 $selection.AddIndent = $false $selection.IndentLevel = 0 $selection.ShrinkToFit = $false $selection.ReadingOrder = $xlContext $selection.MergeCells = $false $selection.Borders.Item($xlInsideHorizontal).Weight = $xlThin #Make everything fit in it's cell. $d.EntireColumn.AutoFit() | Out-Null #Save the file as .xlsx on every placed IP to ensure the file is not lost due to any reason. $b.SaveAs("$FileXML") #Clear screen on every checked IP to remove the 'True' statement. #cls # #Save final result as a .htm file $b.SaveAs("$FileHTML",$xlExcelHTML) #Close and quit Excel. $b.Close() get-process *Excel* | Stop-Process -force #Move .txt file to the correct HTML folder. move-item $file $path2 -Force #Move .xlsx file to the correct HTML folder. move-item $filexml $path2 -Force #Declare XLSX file for mail $MailXML = "$path2\IP-$Date.xlsx" #Clear screen, again. (Let's keep things tidy.) #cls #Variables for public IP # I am defining website url in a variable $url = "http://checkip.dyndns.com" # Creating a new .Net Object names a System.Net.Webclient $webclient = New-Object System.Net.WebClient # In this new webdownlader object we are telling $webclient to download the # url $url $IpPublic = $webclient.DownloadString($url) # Just a simple text manuplation to get the ipadress form downloaded URL # If you want to know what it contain try to see the variable $IpPublic $IpPublic2 = $IpPublic.ToString() $ipPublic3 = $IpPublic2.Split(" ") $ipPublic4 = $ipPublic3[5] $ipPublic5 = $ipPublic4.replace("</body>","") $FinalIPAddress = $ipPublic5.replace("</html>","") $ipLocal = (Get-WmiObject -class win32_NetworkAdapterConfiguration -Filter 'ipenabled = "true"').ipaddress[0] #Variables e-mail. $From = "Blocked IP <r.van.tour@$Company>" $To = "IT Dept <r.van.tour@$Company>" $CC = "Someone <$Company2@$Company" $Subject = "Blocked IPs for $date ($Count Total)" #The href should point to the htm file in your iis/apache folder. $WebLink = $FinalIPAddress+$FileHtmlWeb $here = "<a href='http://$Weblink'><b>Here</b></a>" #Define the body of your e-mail, in this case it displays a message and shows the server it is send from with it's local IP. #A link to the .htm file, how many IP's were blocked and the date of the message. $Body = "<!DOCTYPE html><html><head> <title>Blocked IP's $Date</title></head><header><h1>Blocked IP</h1><p><time pubdate datetime='$date'></time></p></header><br>" $body += "<body>Dear <font color=black>$to</font>,<br><br>" $body += "This is an automated message generated by server: <font color=red><b>$env:COMPUTERNAME, $IPLocal.</b></font><br><br>" $body += "Click <font color=red><b>$here</b></font> to see the Blocked IP report for $date containing $count IP's.<br>" $body += "Or see the attachment to open it in Excel.<br></body></html>" #Clear screen, again. (Let's keep things tidy.) #cls #Send output as e-mail. $SMTPServer = "smtp.gmail.com" $SMTPPort = "587" $Username = "##@gmail.com" $Password = "##" $message = New-Object System.Net.Mail.MailMessage $message.IsBodyHTML = $true $message.ReplyTo = $From $message.Sender = $From $message.subject = $subject $message.body = $body $message.to.add($to) $message.from = $From $message.attachments.add($MailXML) $smtp = New-Object System.Net.Mail.SmtpClient($SMTPServer, $SMTPPort); $smtp.EnableSSL = $true $smtp.Credentials = New-Object System.Net.NetworkCredential($Username, $Password); $smtp.send($message) #Create a function to relase Com object at end of script. function Release-Ref ($ref) { ([System.Runtime.InteropServices.Marshal]::ReleaseComObject( [System.__ComObject]$ref) -gt 0) [System.GC]::Collect() [System.GC]::WaitForPendingFinalizers() } #Release COM Object [System.Runtime.InteropServices.Marshal]::ReleaseComObject([System.__ComObject]$a) | Out-Null #Clear screen for the final time. (Let's keep things tidy.) #cls #Exit powershell exit 

@TheMadTechnician

这个脚本的这个部分似乎有一个问题,那就是在$ DNSResults中无法显示未parsing的IP地址

 $Keywords = "Google","Cloudflare","Cloud","Ping","Easy- Voyage","McAfee","Pingdom","Panopta","Scoot","Uniglobe" $Filter = "($(($Keywords|%{[RegEx]::Escape($_)}) -join "|"))" #Define error actions. #$erroractionpreference = "SilentlyContinue" #Get content from given IP list. $colComputers = @(get-content $File | Sort -unique) $SourceCount = $colComputers.Count write-output "$SourceCount IP's detected." #Get DNS Results $Progress=1 $DNSResults = $colComputers | %{ Write-Progress -Activity "Creating a usable 'Blocked IP' list ($Progress/$sourcecount)" -PercentComplete ($Progress/$sourceCount*100) -Status "Please stand by" try { ($dnsresult = [System.Net.DNS]::GetHostEntry($_))|out-null } catch { $dnsresult = "Fail" } [PSCustomObject][Ordered]@{ Source=$_.ToUpper() HostName=$dnsresult.HostName IPAddress=$dnsresult.AddressList[0].ToString() } $Progress++ } $count = ($DNSResults|?{$_ -match $filter}).count 

好的,我猜你已经从脚本中find了,并且把它们拼凑在一起,因为它被放在一起的方式似乎是一种无计划的。 就像增加和修改的东西一样,没有一个总体规划把它放在一起。 那么,从哪里开始呢? 随着进度条,我已经解决了。

进度栏

$i=1 ForEach($strComputer in $colComputers)并在$intRow = $intRow + 1 (可缩写为$intRow++ )后面添加$i++ 。 但是我们已经知道了。 由于我已经重新编写了一些脚本,所以这种做法已经成为一个有争议的问题,但实际上,您将会看到下一步的ForEach循环。

ForEach循环

接下来,你的ForEach循环。 男孩,那里真是太酷了。 你正在做的事情,一切都完成后,真的只需要做一次。 那么,循环之后我们该怎么办呢? 我们先从几乎所有事情开始。 单元格格式? 后来。 填充细胞? 后来。 sorting? 后来。 调整列宽? 后来。 保存文件? 后来!

那么,这是什么让我们在循环? 实际上并不多,只留下进度条和检查DNS条目。 为什么这样呢? 因为我们可以在PowerShell中用你想要的数据创build一个数组,对数据进行sorting,从数组中只select你想要使用的字段,然后一次粘贴所有的数据而不是一个logging,之后格式化。 事实上,格式化可能会更好,而不是检查单元格是否为空白,并将它们着色为红色,只是将条件格式应用于它们,这样如果它们为空,它们将显示为红色,并让Excel为您完成工作。

这会使脚本运行得更快,因为您不是多次执行相同的工作,而是使用PowerShell中的原始数据而不是使Excel执行此操作。 我最终将您的ForEach循环缩减为几行:

 #Get DNS Results $Progress=1 $DNSResults = $colComputers | %{ Write-Progress -Activity "Creating a usable 'Blocked IP' list ($Progress/$count)" -PercentComplete ($Progress/$Count*100) -Status "Please stand by" try { ($dnsresult = [System.Net.DNS]::GetHostEntry($_))|out-null } catch { $dnsresult = "Fail" } [PSCustomObject][Ordered]@{ Source=$_.ToUpper() HostName=$dnsresult.HostName IPAddress=$dnsresult.AddressList[0].ToString() } $Progress++ } 

这将循环通过条目,并创build一个自定义对象的数组有3个属性,这是你想要在电子表格中的3个单元格。

Excel设置

好的,就格式化和注入简单的文本而言,显然你已经掌握了一些东西,所以我现在要盯上你的标题设置,并把处理后的数据放到电子表格中。

对于数据数组(例如,您正在放入的数据的计算机/主机名/ IP数组),将其作为制表符分隔的CSV对象粘贴到Excel中更为容易。 Out-Clipboard不是一个标准的PowerShell cmdlet,即使我认为它应该是。 另一方面,Clip.exe标准的Windows,所以我们可以为它设置一个别名(如果你有PowerShell社区扩展已经为你完成)。 我把它放在脚本的顶部,以避免它。 通常我会把它放在任何我已经在脚本中设置的function之后,如果我需要设置一个这样的别名。 它检查你是否有Out-Clipboard,如果你没有设置Clip.exe到Out-Clipboard的别名。

 If(!(Get-Command Out-Clipboard -ErrorAction SilentlyContinue)){Set-Alias Out-Clipboard "$env:SYSTEMROOT\System32\clip.exe"} 

现在我们可以把东西放到剪贴板上,这对于我们接下来要做的事情来说真的很方便。 我们将采取我们的数组,并将其转换为制表符分隔的CSV(没有types信息),跳过第一个条目(标题行),sortingHostName留下,并将其pipe道到剪贴板。

 $DNSResults | Sort HostName | ConvertTo-Csv -Delimiter "`t" -NoTypeInformation | Select -Skip 1 | Out-Clipboard 

现在我们只需将其粘贴到Excel中。 要做到这一点,我们需要一个范围对象来指定目标,所以我会设置它,然后使用WorkSheet对象的粘贴(范围,链接)方法。 不要担心链接部分,我们将使用$ false布尔值,因为我们不会将粘贴的数据链接到数据源以进行dynamic更新。 这看起来像这样:

 $e = $c.Range("A3:E$($DNSResults.Count+2)") $c.Paste($e,$false) 

然后,我们继续为您的结果设置颜色,并设置其余的格式。

那么…为什么我们要改变呢?

所以,我最喜欢的叔叔总是告诉我,长大了“如果没有坏,就不要修理” 。 你的脚本做了你想要的,那么为什么我修改它,如果它没有被打破? 这些变化并不是很大,实际上是加快速度,一次插入所有内容,而不是一次插入所有内容,但最重要的是现在我们可以在插入到Excel之前在PowerShell中进行筛选,并将其引导到您的原始问题:

  • 将空白单元格设置为黄色。
  • 将关键字与行匹配,删除所有其他行。

寻找和摧毁!

我们会在一秒钟内到达空白处,但删除没有特定关键词的行现在很容易。 不要删除它们,只是不要插入它们开始! 设置要过滤的单词列表非常简单,然后在导出到剪贴板时仅包含那些单词的logging。

 $Keywords = "Google","Facebook","HappyTreeFriends" $Filter = "($(($Keywords|%{[RegEx]::Escape($_)}) -join "|"))" 

第二行创build一个string,您可以执行RegEx匹配。 它把你的关键字,转义任何特殊字符,join一个pipe道分离他们,并把它们括在括号中。 经过这两行$Filter = (Google|Facebook|HappyTreeFriends) 。 然后在你想要发送数据到剪贴板的那一行上添加一个Where子句:

 $DNSResults | Where{$_ -match $filter} | Sort HostName | ConvertTo-Csv -Delimiter "`t" -NoTypeInformation | Select -Skip 1 | Out-Clipboard 

这样,只有logging中包含黑名单的logging才会插入到Excel中,而且您不必担心返回和删除行。 你想要有关键词的行被突出显示为红色? 只要用这种方法给它们着色(现在你已经把它们设置为颜色索引15,灰色,把它改为3,它们就会变成红色),因为它们应该是唯一的东西。

less了什么东西?

空白单元格可能很难find,特别是一旦你得到一些格式化,并有更less的定义的单元格边界。 在这种情况下find空单元格是很容易的。 我们已经有了$ e,它是一个范围对象,它包含了我们刚刚插入到Excel中的所有数据,甚至是空白单元格。 范围对象基本上是一个单元格的集合,每个单元格都有它自己的属性,比如它的位置(行,列),格式,值等等。你可以做的很简单:

 #If there is no Out-Clipboard, set it If(!(Get-Command Out-Clipboard -ErrorAction SilentlyContinue)){Set-Alias Out-Clipboard "$env:SYSTEMROOT\System32\clip.exe"} #Get current date $Date = get-date -format yyyy-MM-dd $Company = "company" $Company2 = "company2" #Define all files/Paths. $Path = "C:\$Company2\BlockedIP" md "$Path\HTML\$Date" -Force |Out-Null $path2 = "$Path\HTML\$Date" $PathWeb = "/HTML/$Date" #Path = C:/$Company2/BlockedIP #Path2 = C:/$Company2/BlockedIP/HTML/2014-07-09 #Define File's used or created in this script. $File = "$Path\IP-$Date.txt" $FileHtml = "$Path2\IP-$Date.htm" $FileXML = "$Path\IP-$Date.xlsx" $FileHTMLWeb = "$PathWeb\IP-$date.htm" #File = C:/$Company2/BlockedIP/IP-2014-07-09.txt #FileXML = C:/$Company2/BlockedIP/HTML/2014-07-09/IP-2014-07-09.htm #FileHtml = C:/$Company2/BlockedIP/HTML/2014-07-09/IP-2014-07-09.xlsx #FileHTMLWeb = PublicIP/HTML/2014-07-09/IP-2014-07-09.htm $Keywords = "Google","thenetworkfactory" $Filter = "($(($Keywords|%{[RegEx]::Escape($_)}) -join "|"))" #Define error actions. #$erroractionpreference = "SilentlyContinue" #Get content from given IP list. $colComputers = @(get-content $File | Sort -unique) $SourceCount = $colComputers.Count write-output "$Count IP's detected." #Get DNS Results $Progress=1 $DNSResults = $colComputers | %{ Write-Progress -Activity "Creating a usable 'Blocked IP' list ($Progress/$sourcecount)" -PercentComplete ($Progress/$sourceCount*100) -Status "Please stand by" try { ($dnsresult = [System.Net.DNS]::GetHostEntry($_))|out-null } catch { $dnsresult = "Fail" } [PSCustomObject][Ordered]@{ Source=$_.ToUpper() HostName=$dnsresult.HostName IPAddress=$dnsresult.AddressList[0].ToString() } $Progress++ } $count = ($DNSResults|?{$_ -match $filter}).count #Open Excel. $a = New-Object -comobject Excel.Application #Since we want this script to look like it's being used without excel I set it's visibility to false. $a.visible = $True #Disable excel confirmations. $a.DisplayAlerts = $False <# # set interactive to false so nothing from excel is shown. $Excel.DisplayAlerts = $false $Excel.ScreenUpdating = $false $Excel.Visible = $false $Excel.UserControl = $false $Excel.Interactive = $false #> #Create sheets in Excel. $b = $a.Workbooks.Add() $c = $b.Worksheets.Item(1) $c.Activate() | Out-Null #Create a Title for the first worksheet and adjust the font $c.Cells.Item(1,1)= "Blocked IP's $Date" $c.Cells.Item(1,1).Font.ColorIndex = 55 $c.Cells.Item(1,1).Font.Color = 8210719 $range = $c.Range("a1","e1") $range.Style = 'Title' $range.Select() $range.MergeCells = $true $range.VerticalAlignment = -4108 $CounterRow = $Count+5 #Define subjects. $c.Name = "Blocked IP's ($Date)" $c.Cells.Item(2,1) = "Given IP" $c.Cells.Item(2,2) = "Resolved DNS" $c.Cells.Item(2,3) = "Returned IP" $c.Cells.Item(2,5) = "$Company" $c.Cells.Item($Count+5,1) = "Created by" $link = "http://www.$Company" $link2 = "https://www.linkedin.com/profile/view?id=#########" $r = $c.Range("E2") [void]$c.Hyperlinks.Add($r, $link) $r = $c.Range("A$Counterrow") [void]$c.Hyperlinks.Add($r, $link) #Define cell formatting from subjects. $c.Range("A2:E2").Interior.ColorIndex = 6 $c.Range("A2:E2").font.size = 13 $c.Range("A2:E2").Font.ColorIndex = 1 $c.Range("A2:E2").Font.Bold = $True #Define html code for Excel save to .htm. $xlExcelHTML = 44 #Define the usedrange, excluding header and footer rows $e = $c.Range("A3:E$(2+$Count)") #Populate data into spreadsheet $DNSResults | Where{$_ -match $filter} | Sort HostName | ConvertTo-Csv -Delimiter "`t" -NoTypeInformation | Select -Skip 1 | Out-Clipboard #$c.Cells.Item(3,1).Select() $c.Paste($e,$false) ForEach($Cell in $e){ If([String]::IsNullOrWhitespace($Cell.value2)){$Cell.interior.colorindex=6} } #Define the usedrange for autofitting. $d = $c.UsedRange #Set background color for the IP list. $E.interior.colorindex = 15 #Define borders here. $xlOpenXMLWorkbook = 51 $xlAutomatic=-4105 $xlBottom = -4107 $xlCenter = -4108 $xlRight = -4152 $xlContext = -5002 $xlContinuous=1 $xlDiagonalDown=5 $xlDiagonalUp=6 $xlEdgeBottom=9 $xlEdgeLeft=7 $xlEdgeRight=10 $xlEdgeTop=8 $xlInsideHorizontal=12 $xlInsideVertical=11 $xlNone=-4142 $xlThin=2 $selection = $c.range("A3:C$($DNSResults.Count+2)") $selection.select() |out-null $selection.HorizontalAlignment = $xlRight $selection.VerticalAlignment = $xlBottom $selection.WrapText = $false $selection.Orientation = 0 $selection.AddIndent = $false $selection.IndentLevel = 0 $selection.ShrinkToFit = $false $selection.ReadingOrder = $xlContext $selection.MergeCells = $false $selection.Borders.Item($xlInsideHorizontal).Weight = $xlThin #Make everything fit in it's cell. $d.EntireColumn.AutoFit() | Out-Null #Save the file as .xlsx on every placed IP to ensure the file is not lost due to any reason. $b.SaveAs("$FileXML") #Clear screen on every checked IP to remove the 'True' statement. #cls # #Save final result as a .htm file $b.SaveAs("$FileHTML",$xlExcelHTML) #Close and quit Excel. $b.Close() get-process *Excel* | Stop-Process -force #Move .txt file to the correct HTML folder. move-item $file $path2 -Force #Move .xlsx file to the correct HTML folder. move-item $filexml $path2 -Force #Declare XLSX file for mail $MailXML = "$path2\IP-$Date.xlsx" #Clear screen, again. (Let's keep things tidy.) #cls #Variables for public IP # I am defining website url in a variable $url = "http://checkip.dyndns.com" # Creating a new .Net Object names a System.Net.Webclient $webclient = New-Object System.Net.WebClient # In this new webdownlader object we are telling $webclient to download the # url $url $IpPublic = $webclient.DownloadString($url) # Just a simple text manuplation to get the ipadress form downloaded URL # If you want to know what it contain try to see the variable $IpPublic $IpPublic2 = $IpPublic.ToString() $ipPublic3 = $IpPublic2.Split(" ") $ipPublic4 = $ipPublic3[5] $ipPublic5 = $ipPublic4.replace("</body>","") $FinalIPAddress = $ipPublic5.replace("</html>","") $ipLocal = (Get-WmiObject -class win32_NetworkAdapterConfiguration -Filter 'ipenabled = "true"').ipaddress[0] #Variables e-mail. $From = "Blocked IP <r.van.tour@$Company>" $To = "IT Dept <r.van.tour@$Company>" $CC = "Someone <$Company2@$Company" $Subject = "Blocked IPs for $date ($Count Total)" #The href should point to the htm file in your iis/apache folder. $WebLink = $FinalIPAddress+$FileHtmlWeb $here = "<a href='http://$Weblink'><b>Here</b></a>" #Define the body of your e-mail, in this case it displays a message and shows the server it is send from with it's local IP. #A link to the .htm file, how many IP's were blocked and the date of the message. $Body = "<!DOCTYPE html><html><head> <title>Blocked IP's $Date</title></head><header><h1>Blocked IP</h1><p><time pubdate datetime='$date'></time></p></header><br>" $body += "<body>Dear <font color=black>$to</font>,<br><br>" $body += "This is an automated message generated by server: <font color=red><b>$env:COMPUTERNAME, $IPLocal.</b></font><br><br>" $body += "Click <font color=red><b>$here</b></font> to see the Blocked IP report for $date containing $count IP's.<br>" $body += "Or see the attachment to open it in Excel.<br></body></html>" #Clear screen, again. (Let's keep things tidy.) #cls #Send output as e-mail. $SMTPServer = "smtp.gmail.com" $SMTPPort = "587" $Username = "##@gmail.com" $Password = "##" $message = New-Object System.Net.Mail.MailMessage $message.IsBodyHTML = $true $message.ReplyTo = $From $message.Sender = $From $message.subject = $subject $message.body = $body $message.to.add($to) $message.from = $From $message.attachments.add($MailXML) $smtp = New-Object System.Net.Mail.SmtpClient($SMTPServer, $SMTPPort); $smtp.EnableSSL = $true $smtp.Credentials = New-Object System.Net.NetworkCredential($Username, $Password); $smtp.send($message) #Create a function to relase Com object at end of script. function Release-Ref ($ref) { ([System.Runtime.InteropServices.Marshal]::ReleaseComObject( [System.__ComObject]$ref) -gt 0) [System.GC]::Collect() [System.GC]::WaitForPendingFinalizers() } #Release COM Object [System.Runtime.InteropServices.Marshal]::ReleaseComObject([System.__ComObject]$a) | Out-Null #Clear screen for the final time. (Let's keep things tidy.) #cls #Exit powershell exit 

编辑:我发现你的脚本的问题。 您没有更新要复制到剪贴板的行,而是在脚本已经粘贴到Excel之后,稍后在脚本中添加行,以便您添加的代码无效。 我已经对你的代码做了一些更新(更好地处理logging计数,并正确地过滤),并更新了上面的脚本。

编辑2:这个职位的人变得越来越长。 好的,所以要包括我修改了一些东西的所有条目。 首先是查找DNS结果的ForEach循环,我修改了对象创build行,在尝试填充之前检查它们是否存在,以便停止对DNS查找没有HostName和IP地址中的一个或两个的事物抛出错误。

 [PSCustomObject][Ordered]@{ Source=$_.ToUpper() HostName=$(if(!([string]::IsNullOrEmpty($dnsresult.HostName))){$dnsresult.HostName}) IPAddress=$(if(!([string]::IsNullOrEmpty($dnsresult.AddressList))){$dnsresult.AddressList[0].ToString()}) } 

然后我把结果分成三类:主机名匹配关键字,主机名不匹配关键字,没有主机名(也改变$ count wince我们包括所有内容)。

 $DNSWithKeyword = $DNSResults | ?{$_.HostName -match $Filter} $DNSNoKeyword = $DNSResults | ?{!($_.HostName -match $Filter) -and !([string]::IsNullOrEmpty($_.HostName))} $DNSLookupFailed = $DNSResults | ?{([string]::IsNullOrEmpty($_.HostName))} #$count = ($DNSResults|?{$_ -match $filter}).count $count = $SourceCount 

然后在定义了使用范围的方法中,我为每个类别添加了一个,而不是一个复制/粘贴我做三个,所以首先有匹配关键字,按主机名sorting,然后没有按主机名sorting的关键字,然后那些没有主机名。 然后,我逐一地上色,然后又回来了,空白的细胞又变成了黄色。

 #Define the usedrange, excluding header and footer rows $KeyRange = $c.Range("A3:E$(2+$DNSWithKeyword.Count)") $NoKeyRange = $c.Range("A$(2+$DNSWithKeyword.Count+1):E$(2+$DNSWithKeyword.Count+$DNSNoKeyword.Count)") $NoDNSRange = $c.Range("A$(2+$DNSWithKeyword.Count+$DNSNoKeyword.Count+1):E$(2+$DNSWithKeyword.Count+$DNSNoKeyword.Count+$DNSLookupFailed.Count)") $e = $c.Range("A3:E$(2+$Count)") #Populate data into spreadsheet $DNSWithKeyword | Sort HostName | ConvertTo-Csv -Delimiter "`t" -NoTypeInformation | Select -Skip 1 | Out-Clipboard $c.Paste($KeyRange,$false) $DNSNoKeyword | Sort HostName | ConvertTo-Csv -Delimiter "`t" -NoTypeInformation | Select -Skip 1 | Out-Clipboard $c.Paste($NoKeyRange,$false) $DNSLookupFailed | ConvertTo-Csv -Delimiter "`t" -NoTypeInformation | Select -Skip 1 | Out-Clipboard $c.Paste($NoDNSRange,$false) #Define the usedrange for autofitting. $d = $c.UsedRange #Set background color for the IP list. $KeyRange.interior.colorindex = 3 $NoKeyRange.interior.colorindex = 15 $NoDNSRange.interior.colorindex = 14 ForEach($Cell in $e){ If([String]::IsNullOrWhitespace($Cell.value2)){$Cell.interior.colorindex=6} }