Как заполнить ячейку в CSV из PowerShell

Я пытаюсь проверить некоторые URI на основе некоторых доменов в CSV. Пока это работает благодаря командлету Invoke-WebRequest в PowerShell. Любой ответ «200» со страницы, и я знаю, что он действителен. (Я также нашел хорошую функцию, чтобы сделать это проще)

Однако там, где я застреваю, просто обновляется CSV-файл, полный сайтов, с проверенным URL-адресом.

Итак, мой CSV, например,

CompanyName,Domain
Google, Google.com
Microsoft, Microsoft.com
NotARealCompany, NotARealWebsite123.com

В настоящее время мой обходной путь состоит в том, чтобы просто иметь один столбец (удалить заголовок и просто перечислить домены в текстовом файле), и мой скрипт теперь будет проверять ссылки, которые возвращают HTTP-ответ 200, и экспортировать его в новый текстовый файл ( см код).

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 ответа (если он действителен) или «Недействителен», если это не так, например

CompanyName,Domain
Google, https://www.google.com
Microsoft, https://www.microsoft.com
NotARealCompany, InvalidDomain

Это была моя попытка, но я не могу передать 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-Csv и Export-Csv.

Ansgar Wiechers 08.04.2019 16:44

Привет @AndersWiechers, спасибо за это! Я знаю, что мне нужно использовать эти командлеты, но я изо всех сил пытался использовать их правильно, поэтому я не привел пример. Мой плохой, должен был объяснить.

Pete Symonds 09.04.2019 10:40

Нет, вы должны были показано попытаться использовать их, даже если это не сработало. На самом деле ожидается, что код, размещенный здесь, не будет работать (иначе вы, вероятно, вообще не задавали бы вопрос). В нынешнем виде ваш вопрос не показывает попытку решить проблему самостоятельно, а вместо этого просит: «Пожалуйста, перепишите этот фрагмент кода в соответствии с моими требованиями». Что осуждается здесь.

Ansgar Wiechers 09.04.2019 10:56

Вы правы, поэтому я отредактирую свой код, чтобы показать свою первоначальную попытку. Имейте в виду, что иногда людям немного стыдно за наши попытки, но скрывать это тоже не помогает... Так что спасибо за помощь. Ценить это.

Pete Symonds 09.04.2019 11:37
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
94
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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, что работает для самой верхней строки, но не для остальных

Pete Symonds 09.04.2019 10:33

Также я добавил функцию в блок сценария, чтобы она была более полной. Не знаю, почему я не сделал этого раньше.

Pete Symonds 09.04.2019 10:37

аааа, проблемы с написанием кода слишком быстро... конечно Хэш-таблицы не поддерживают op_Addition... только массивы ;-) Тогда, наверное, мне следует определить один! Я отредактировал свой пост, чтобы исправить код.

HAL9256 09.04.2019 19:08

Потрясающий! Спасибо. Вчера вечером я потратил на это немного времени, но мне не хватало создания выходного массива внизу. Имеет смысл, когда вы это видите.

Pete Symonds 10.04.2019 13:05

Другие вопросы по теме