【问题标题】:How do I populate cell in CSV from PowerShell如何从 PowerShell 填充 CSV 中的单元格
【发布时间】:2019-08-29 17:27:57
【问题描述】:

我正在尝试根据 CSV 中的某些域来验证某些 URI。 到目前为止,这要归功于 PowerShell 中的 Invoke-WebRequest cmdlet。来自页面的任何“200”响应,我都知道它是有效的。 (我还发现了一个很好的函数来使它更容易)

但是,我卡住的地方只是使用经过验证的 URL 更新充满网站的 CSV 文件。

所以我的 CSV 就是这个例子

公司名称、域名 谷歌, Google.com 微软, Microsoft.com NotARealCompany, NotARealWebsite123.com

目前我的解决方法是只使用一个列(去除标题并仅列出 txt 文件中的域),我的脚本现在将验证返回 200 的 HTTP 响应的链接并将其导出到新的txt 文件(见代码)。

Function Test-URI {
<#
.Synopsis
Test a URI or URL
.Description
This command will test the validity of a given URL or URI that begins with either http or https. The default behavior is to write a Boolean value to the pipeline. But you can also ask for more detail.

Be aware that a URI may return a value of True because the server responded correctly. For example this will appear that the URI is valid.

test-uri -uri http://files.snapfiles.com/localdl936/CrystalDiskInfo7_2_0.zip

But if you look at the test in detail:

ResponseUri   : http://files.snapfiles.com/localdl936/CrystalDiskInfo7_2_0.zip
ContentLength : 23070
ContentType   : text/html
LastModified  : 1/19/2015 11:34:44 AM
Status        : 200

You'll see that the content type is Text and most likely a 404 page. By comparison, this is the desired result from the correct URI:

PS C:\> test-uri -detail -uri http://files.snapfiles.com/localdl936/CrystalDiskInfo6_3_0.zip

ResponseUri   : http://files.snapfiles.com/localdl936/CrystalDiskInfo6_3_0.zip
ContentLength : 2863977
ContentType   : application/x-zip-compressed
LastModified  : 12/31/2014 1:48:34 PM
Status        : 200

.Example
PS C:\> test-uri https://www.petri.com
True
.Example
PS C:\> test-uri https://www.petri.com -detail

ResponseUri   : https://www.petri.com/
ContentLength : -1
ContentType   : text/html; charset=UTF-8
LastModified  : 1/19/2015 12:14:57 PM
Status        : 200
.Example
PS C:\> get-content D:\temp\uris.txt | test-uri -Detail | where { $_.status -ne 200 -OR $_.contentType -notmatch "application"}

ResponseUri   : http://files.snapfiles.com/localdl936/CrystalDiskInfo7_2_0.zip
ContentLength : 23070
ContentType   : text/html
LastModified  : 1/19/2015 11:34:44 AM
Status        : 200

ResponseURI   : http://download.bleepingcomputer.com/grinler/rkill
ContentLength : 
ContentType   : 
LastModified  : 
Status        : 404

Test a list of URIs and filter for those that are not OK or where the type is not an application.
.Notes
Last Updated: January 19, 2015
Version     : 1.0

Learn more about PowerShell:
http://jdhitsolutions.com/blog/essential-powershell-resources/

  ****************************************************************
  * DO NOT USE IN A PRODUCTION ENVIRONMENT UNTIL YOU HAVE TESTED *
  * THOROUGHLY IN A LAB ENVIRONMENT. USE AT YOUR OWN RISK.  IF   *
  * YOU DO NOT UNDERSTAND WHAT THIS SCRIPT DOES OR HOW IT WORKS, *
  * DO NOT USE IT OUTSIDE OF A SECURE, TEST SETTING.             *
  ****************************************************************

.Link
Invoke-WebRequest
#>

[cmdletbinding(DefaultParameterSetName="Default")]
Param(
[Parameter(Position=0,Mandatory,HelpMessage="Enter the URI path starting with HTTP or HTTPS",
ValueFromPipeline,ValueFromPipelineByPropertyName)]
[ValidatePattern( "^(http|https)://" )]
[Alias("url")]
[string]$URI,
[Parameter(ParameterSetName="Detail")]
[Switch]$Detail,
[ValidateScript({$_ -ge 0})]
[int]$Timeout = 30
)

Begin {
    Write-Verbose -Message "Starting $($MyInvocation.Mycommand)" 
    Write-Verbose -message "Using parameter set $($PSCmdlet.ParameterSetName)" 
} #close begin block

Process {

    Write-Verbose -Message "Testing $uri"
    Try {
     #hash table of parameter values for Invoke-Webrequest
     $paramHash = @{
     UseBasicParsing = $True
     DisableKeepAlive = $True
     Uri = $uri
     Method = 'Head'
     ErrorAction = 'stop'
     TimeoutSec = $Timeout
    }

    $test = Invoke-WebRequest @paramHash

     if ($Detail) {
        $test.BaseResponse | 
        Select ResponseURI,ContentLength,ContentType,LastModified,
        @{Name="Status";Expression={$Test.StatusCode}}
     } #if $detail
     else {
       if ($test.statuscode -ne 200) {
            #it is unlikely this code will ever run but just in case
            Write-Verbose -Message "Failed to request $uri"
            write-Verbose -message ($test | out-string)
            $False
         }
         else {
            $True
         }
     } #else quiet

    }
    Catch {
      #there was an exception getting the URI
      write-verbose -message $_.exception
      if ($Detail) {
        #most likely the resource is 404
        $objProp = [ordered]@{
        ResponseURI = $uri
        ContentLength = $null
        ContentType = $null
        LastModified = $null
        Status = 404
        }
        #write a matching custom object to the pipeline
        New-Object -TypeName psobject -Property $objProp

        } #if $detail
      else {
        $False
      }
    } #close Catch block
} #close Process block

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

}
    $DomainList = Get-Content C:\temp\Sites.txt

    foreach ($Domain in $DomainList) {
        $Result = Test-URI -URI "http://$Domain" -Detail -Timeout 5

        if ($Result.Status -eq "200") {
            $Result.ResponseUri.OriginalString |
                Out-File -FilePath C:\temp\DomainExport.txt -Append
        } else {
            Write-Host "$Link did not respond....."
        }
    }

我希望更新 CSV,以便使用经过验证的响应 URI(如果有效)或“无效”更新每个域,如果不是,例如

公司名称、域名 谷歌,https://www.google.com 微软,https://www.microsoft.com NotARealCompany,无效域

这是我的尝试,但我似乎无法将 Import-CSV 通过管道传输到 ForEach ...

    $DomainListOriginal = Import-Csv C:\temp\Sites.csv


    $DomainListOriginal | ForEach ($Domain.Domain in $DomainList) {

    $Result = Test-URI -URI "http://$Domain" -Detail -Timeout 5

    $DomainListAfter = @()

    If ($Result.Status -eq "200")

    {$DomainListAfter = $Result.ResponseUri.OriginalString}

    Else
    {Write-Host "$Link did not respond....."}

    }


    $DomainListAfter | Export-Csv C:\temp\DomainExport.csv -NoTypeInformation

【问题讨论】:

  • 您正在寻找Import-CsvExport-Csv
  • 嗨@AndersWiechers,谢谢!我知道我需要使用这些 cmdlet,但我很难正确使用它们,所以我没有提供示例。我的错,应该解释一下。
  • 不,你应该显示你尝试使用它们,即使那不起作用。实际上,此处发布的代码预计将不起作用(否则您可能不会首先发布问题)。就目前而言,您的问题并未显示自己尝试解决问题,而是询问“请根据我的要求重写这段代码”。这是不受欢迎的。
  • 你是对的,所以我将编辑我的代码以显示我最初的尝试。请记住,有时人们会为我们的尝试感到羞耻,但隐藏它也无济于事......所以感谢您帮助我。欣赏它。

标签: powershell csv export


【解决方案1】:

为了扩展@AnsgarWiechers,它看起来像这样:

$DomainList = Import-Csv C:\temp\Sites.csv

#Create Empty array to hold results
$Output = @()

foreach ($Domain in $DomainList) {
    $Link = "http://$($Domain.Domain)"
    $Result = Test-URI -URI $Link -Detail -Timeout 5

    #Pre-load Temporary output object with CSV structure
    $DomainOutput = $Domain

    if ($Result.Status -eq "200") {
        $DomainOutput.Domain = $Result.ResponseUri.OriginalString
    } else {
        $DomainOutput.Domain = "InvalidDomain"
        Write-Host "$Link did not respond....."
    }

    #Add to our Output Array
    $Output += $DomainOutput
}

$Output | Export-Csv C:\temp\DomainExport.csv -NoTypeInformation

【讨论】:

  • 这太棒了!它让我更接近。我现在只是得到一个错误有什么想法吗? Method invocation failed because [System.Management.Automation.PSObject] does not contain a method named 'op_Addition'. At D:\Scripts\Get-SiteStatusTest.ps1:182 char:9 + $Output += $Domain + ~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (op_Addition:String) [], RuntimeException + FullyQualifiedErrorId : MethodNotFound 我尝试将 $Output += $Domain 更改为 $Output = [Array]$Output + $Domain,它适用于最上面的一行,但不适用于其余部分
  • 我还在脚本块中添加了该功能,使其更加完整。不知道为什么我以前没有这样做。
  • 啊,写代码太快的麻烦... 当然 Hashtables 不支持op_Addition... 只有数组 ;-) 我应该定义一个然后!我已经编辑了我的帖子以修复代码。
  • 太棒了!谢谢。我昨晚自己花了一些时间在上面,但我错过了在底部创建输出数组。当你看到它时才有意义。
猜你喜欢
  • 2018-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-20
  • 2013-02-08
  • 1970-01-01
  • 2021-05-29
相关资源
最近更新 更多