当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] 使用 PowerShell 创建链接的 HTML

作者:精品下载站 日期:2024-12-14 07:56:58 浏览:14 分类:玩电脑

使用 PowerShell 创建链接的 HTML


今天的帖子是关于一个利基问题或一些你以前从未考虑过的问题。虽然我将分享已完成的 PowerShell 函数,但您可能希望根据技术和概念创建自己的工具。问题始于这样的命令:

Get-HotFix -ComputerName $env:computername |
Sort-Object Description,InstalledOn -Descending |
Select-Object Description,HotfixID,Caption,InstalledBy,InstalledOn

假设您想要使用此信息创建一个 HTML 报告,您可以通过将其传递到 ConvertTo-HTML,然后传递到 Out-File 来完成。结果是足够的。

[玩转系统] 使用 PowerShell 创建链接的 HTML

是的,我知道我可以通过应用一种风格来让它变得漂亮,但这无助于解决一个缺点。标题列下的链接不是实际的超链接。如果他们是的话不是很好吗?事实上,您可能有来自许多其他来源的数据,其中包括您想要转换为 html 页面的链接。这是您可能采取的一种方法。

首先,我要将修补程序数据保存为 HTML 片段。

$h = Get-HotFix -ComputerName $env:computername |
Sort-Object Description,InstalledOn -Descending |
Select-Object Description,HotfixID,Caption,InstalledBy,InstalledOn |
ConvertTo-Html -Fragment

我需要做的是更改标题的表定义以包含 <a href=> 标记。我需要做的是像这样更改文本:

<td>http://support.microsoft.com/?kbid=4509096</td>

进入这个:

<td><a href="http://support.microsoft.com/?kbid=4509096">http://support.microsoft.com/?kbid=4509096></a></td>

这听起来像是正则表达式的一个很好的用例。这是一个匹配 url 的模式。

[regex]$rx = "http(s)?:\/\/[a-zA-Z0-9\.\/\?\%=&$-]+"

是的,我知道有很多方法可以定义正则表达式模式,但这足以满足我的示例。

我的方法是遍历 HTML 的每一行,并找到一个匹配的 URL,并将其替换为必要的附加标签。为了简单起见,我将在此处创建一个新字符串,该字符串最终将成为 HTML 文档的正文。

[string]$out = @"
<H1>$env:computername</H1>
"@

接下来,我将浏览 $h 中存储的 HTML 的每一行。如果该行与正则表达式对象匹配,我将获得匹配值并将其保存到变量中。这样我就可以用链接构建替换文本。最后一步是用链接替换该行。这具有仅用新链接替换 http 字符串的效果。

foreach ($line in $h) {
    if ($rx.IsMatch($line)) {
        $value = $rx.Match($line).value
        $link = "<a href = ""$value"" target = ""_blank"">$value</a>"
        $out += $rx.Replace($line, $link)
    }
    else {
        #just add the line
        $out += $line
    }
}

每个新行都会添加到此处的字符串中。如果该行与正则表达式不匹配,我只需将其按原样添加到此处的字符串 $out 中。

[玩转系统] 使用 PowerShell 创建链接的 HTML

您可以看到带有 URL 的 元素现在有一个超链接。剩下的就是将其转换为 HTML 文档。

$head = @"
<title>Hot Fix Report</title>
<style>
table
{
font-family:"Trebuchet MS", Arial, Helvetica, sans-serif;
border-collapse:collapse;
}
td
{
font-size:1em;
border:1px solid #98bf21;
padding:5px 5px 5px 5px;
}
th
{
font-size:1.1em;
text-align:center;
padding-top:5px;
padding-bottom:5px;
padding-right:7px;
padding-left:7px;
background-color:#A7C942;
color:#ffffff;
}
name tr
{
color: #060606;
background-color:#EAF2D3;
}
</style>
"@

Convertto-Html -head $head -body $out -PostContent "<h5><i>report run $(Get-Date) </i></h5>" | out-file D:\temp\hotfix.html

我正在将样式表嵌入到文档中。

[玩转系统] 使用 PowerShell 创建链接的 HTML

当然,让这一切变得更容易的是一个函数。

Function ConvertTo-HTML2 {
    [cmdletbinding()]
    [outputtype([system.string])]
    Param(
        [Parameter(Mandatory, ValueFromPipeline)]
        [object]$InputObject,
        [switch]$Fragment,
        [ValidateSet("Table", "List")]
        [string]$As,
        [string[]]$Head,
        [string]$Title,
        [uri]$CSSUri,
        [string[]]$PostContent,
        [string[]]$PreContent,
        [object[]]$Property
    )
    Begin {
        Write-Verbose "[$((Get-Date).TimeofDay) BEGIN  ] Starting $($myinvocation.mycommand)"
        [regex]$rx = "http(s)?:\/\/[a-zA-Z0-9\.\/\?\%=&$-]+"
        $in = @()
        $processing = $False
    } #begin

    Process {
        if (-Not $processing) {
            #only display this message once
            Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Storing Data "
        }
        $in += $InputObject
        $processing = $True
    } #process

    End {
        Write-Verbose "[$((Get-Date).TimeofDay) END    ] Converting input to html fragment"
        [void]$PSBoundParameters.remove("InputObject")
        $h = $in | ConvertTo-Html @PSBoundParameters
        [string]$out = @"
"@

        foreach ($line in $h) {
            if ($rx.IsMatch($line) -AND ($line -notmatch "DOCTYPE html PUBLIC") -AND ($line -notmatch "html xmlns")) {
                $value = $rx.Match($line).value
                $link = "<a href = ""$value"" target = ""_blank"">$value</a>"
                $out += $rx.Replace($line, $link)
            }
            else {
                #just add the line
                $out += $line
            }
        }
        $out
        Write-Verbose "[$((Get-Date).TimeofDay) END    ] Ending $($myinvocation.mycommand)"
    } #end

} #close ConvertTo-HTML2

该函数本质上是 ConvertTo-HTML 的包装器。参数是相同的,因此我可以简单地将 PSBoundParameters 转换为 ConvertTo-HTML。该函数获取所有输入,然后在 End 块中进行正则表达式替换。该函数最终将 HTML 写入管道,如 ConvertTo-HTML。但现在我可以运行如下命令:

Get-HotFix -ComputerName $env:computername |
Sort-Object Description, InstalledOn -Descending |
ConvertTo-HTML2 -head $head -property  Description, HotfixID, Caption, InstalledBy, InstalledOn -PreContent "<H1>$env:computername</H1>" -PostContent "<h5><i>report run $(Get-Date) </i></h5>" | Out-File D:\temp\t.html

创建相同的报告。此示例使用之前的 $head 变量。我可以将此函数用于任何具有 http 类型链接的内容。

这是我必须获取 RSS feed 的函数。

Function Get-RSSFeed {

    Param (
        [Parameter(Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [ValidateNotNullOrEmpty()]
        [ValidatePattern("^http(s)?:\/\/")]
        [Alias('url')]
        [string[]]$Path = "https://jdhitsolutions.com/blog/feed"
    )

    Begin {
        Write-Verbose -Message "Starting $($MyInvocation.Mycommand)"
    } #begin

    Process {
        foreach ($item in $path) {
            $data = Invoke-RestMethod -Uri $item
            foreach ($entry in $data) {
                #link might be different names
                if ($entry.origLink) {
                    $link = $entry.origLink
                }
                elseif ($entry.link) {
                    $link = $entry.link
                }
                else {
                    $link = "unknown"
                }
                #clean up description
                #hash table of HTML codes
                #http://www.ascii.cl/htmlcodes.htm
                $decode = @{
                    '<(.|\n)+?>' = ""
                    '’'    = "'"
                    '“'    = '"'
                    '”'    = '"'
                    '»'     = "..."
                    '-'    = "--"
                    '…'    = "..."
                    '–'        = "@"
                    ' '     = " "
                }

                #description could be an XML element or a simple string
                if ($entry.description -is [System.Xml.XmlElement]) {
                    $description = $entry.description.innertext
                }
                else {
                    $description = $entry.description
                }

                foreach ($key in $decode.keys) {
                    [regex]$rgx = $key
                    $description = $rgx.Replace($description, $decode.Item($key)).Trim()
                }

                #create a custom object
                [pscustomobject]@{
                    Title       = $entry.title
                    Author      = $entry.creator.innertext
                    Description = $description
                    Published   = $entry.pubDate -as [datetime]
                    Category    = $entry.category.'#cdata-section'
                    Link        = $Link
                } #hash

            } #foreach entry
        } #foreach item

    } #process

    End {
        Write-Verbose -Message "Ending $($MyInvocation.Mycommand)"
    } #end

} #end Get-RSSFeed

我可以使用它创建带有链接的 HTML 报告。

$cparams = @{
    Title = "The Lonely Administrator" 
    CSSUri = "C:\scripts\samplecss\sample2.css"
    Property = "Title","Description","Published","Link"
    As = "table"
}

Get-RSSFeed  | ConvertTo-HTML2 @cparams | Out-File d:\temp\rss.html

[玩转系统] 使用 PowerShell 创建链接的 HTML

我希望您能亲自尝试一下这些代码片段。如果您觉得正则表达式对您来说太难了,请继续关注。我即将结束关于 PowerShell 和正则表达式的 Pluralsight 课程,希望能帮助揭开这个谜团。

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯