【问题标题】:Passing an array of URLs as an argument to Powershell将 URL 数组作为参数传递给 Powershell
【发布时间】:2012-10-17 15:39:27
【问题描述】:

我正在尝试编写一个脚本,该脚本将获取一个包含文档 URL 链接的文本文件并下载它们。我很难理解如何在 powershell 中传递参数和操作它们。这是我到目前为止得到的。我想我应该使用 param 方法来获取参数,这样我就可以在脚本中使用它,但是 $args 在面值上似乎更容易......如果有一点帮助,将不胜感激。 **更新

$script = ($MyInvocation.MyCommand.Name)
$scriptName = ($MyInvocation.MyCommand.Name -replace "(.ps1)" , "")
$scriptPath = ($MyInvocation.MyCommand.Definition)
$scriptDirectory = ($scriptPath.Replace("$script" , ""))

## ##################################
## begin code for directory creation.
## ##################################

## creates a direcory based on the name of the script.
do {
    $scriptFolderTestPath = Test-Path $scriptDirectory\$scriptName -PathType container
    $scriptDocumentFolderTestPath = Test-Path $scriptFolder\$scriptName"_Script_Documents" -PathType container
    $scriptLogFolderTestPath = Test-Path $scriptFolder\$scriptName"_Script_Logs" -PathType container

    if ($scriptFolderTestPath -match "False") { 
        $scriptFolder = New-Item $scriptDirectory\$scriptName -ItemType directory
    }
    elseif ($scriptDocumentFolderTestPath -match "False") {
        New-Item $scriptFolder\$scriptName"_Script_Documents" -ItemType directory       
    }
    elseif ($scriptLogFolderTestPath -match "False") {
        New-Item $scriptFolder\$scriptName"_Script_Logs" -ItemType directory
    }
} Until (($scriptFolderTestPath -match "True") -and ($scriptDocumentFolderTestPath -match "True") -and ($scriptLogFolderTestPath -match "True"))

## variables for downloading and renaming code.
$date = (Get-Date -Format yyyy-MM-dd)

## ################################
## begin code for link downloading.
## ################################

## gets contents of the arguement variable.
Get-Content $linkList

## downloads the linked file.
Invoke-WebRequest $linkList

导致的错误

PS C:\Windows\system32> C:\Users\Steve\Desktop\Website_Download.ps1
cmdlet Website_Download.ps1 at command pipeline position 1
Supply values for the following parameters:
linkList: C:\Users\Steve\Desktop\linkList.txt


    Directory: C:\Users\Steve\Desktop\Website_Download


Mode                LastWriteTime     Length Name                                                                                     
----                -------------     ------ ----                                                                                     
d----        10/27/2012   3:59 PM            Website_Download_Script_Documents                                                        
d----        10/27/2012   3:59 PM            Website_Download_Script_Logs                                                             
Get-Content : Cannot find path 'C:\Users\Steve\Desktop\linkList.txt' because it does not exist.
At C:\Users\Steve\Desktop\Website_Download.ps1:42 char:1
+ Get-Content $linkList
+ ~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\Users\Steve\Desktop\linkList.txt:String) [Get-Content], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand

Invoke-WebRequest : Could not find file 'C:\Users\Steve\Desktop\linkList.txt'.
At C:\Users\Steve\Desktop\Website_Download.ps1:45 char:1
+ Invoke-WebRequest $linkList
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.FileWebRequest:FileWebRequest) [Invoke-WebRequest], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

【问题讨论】:

    标签: parameter-passing powershell-3.0


    【解决方案1】:

    与任何其他类型的参数相比,在 Powershell 中传递参数数组没有区别。 See here 了解它是如何完成的。考虑到你有一个文本文件,你不需要传递一个参数数组,只需要传递一个文件名,所以只是一个字符串。

    我对您正在使用的 Powershell 3.0 没有任何经验(根据您的代码中是否存在 Invoke-WebRequest 来判断),但我会从以下内容开始:

    $URLFile = @"
    http://www.google.ca
    http://www.google.com
    http://www.google.co.uk/
    "@
    
    $URLs = $URLFile -split "`n";
    $savedPages = @();
    foreach ($url in $URLs) {
        $savedPages += Invoke-WebRequest $url   
    }
    

    也就是说,您只有一个文件,都在一个地方,并确保您正确接收您的内容。不知道你为什么需要Start-BitsTransfer,因为Invoke-WebRequest 已经为你提供了页面内容。请注意,我没有对 $savedPages 做任何事情,所以我的代码实际上是无用的。

    之后,$URLFile 的内容进入一个文件,然后您将调用替换为

    gc "Path_To_Your_File"`
    

    如果仍然有效,请在脚本中引入 $Path 参数,如下所示:

    param([string]$Path)
    

    再次测试,以此类推。如果您是 Powershell 新手,请始终从较小的代码片段开始,并不断扩展以包含您需要的所有功能。如果你从一大块开始,很可能你永远不会完成。

    【讨论】:

    • 感谢您的回复。但这对我来说没有意义。为什么我不能只传递一个带有 URL 作为参数的 txt 文件并使用 get-content 将每一行作为一个对象并将它们传递给 Invoke-Webrequest cmdlet?我正在用我添加的参数片段和由此产生的错误更新我的主要帖子。
    • @Steve:我建议你一个起点。忘记外部文件,忘记参数。确保您的单个文件代码按预期工作。是的,然后您将传递一个带有 URL 作为参数的 txt 文件,但您不需要对 URL 执行 get-content。假设文件中的每一行都是一个 URL,您将按换行符拆分并输入 Invoke-Webrequest,这正是我在示例中所做的。
    • 我不喜欢这个起点,因为它更像是一个 perl 脚本。我不应该解析 txt 文件。如果我想手动执行此操作,它将如下所示。 '$links = "C:\Users\Steve\Desktop\linkList.txt" $results = "C:\Users\Steve\Desktop\Results" $crawl = get-content $links Invoke-WebRequest $crawl'
    【解决方案2】:

    通过 Neolisk 中关于处理参数的链接解决了这个问题。然后在最后更改了一些代码以创建另一个变量并像往常一样处理事情。只是与传递参数有些混淆。

    ## parameter passed to the script.
    param (
        [parameter(Position=0 , Mandatory=$true)]
        [string]$linkList
    )
    
    ## variables for dynamic naming.
    $script = ($MyInvocation.MyCommand.Name)
    $scriptName = ($MyInvocation.MyCommand.Name -replace "(.ps1)" , "")
    $scriptPath = ($MyInvocation.MyCommand.Definition)
    $scriptDirectory = ($scriptPath.Replace("$script" , ""))
    
    ## ##################################
    ## begin code for directory creation.
    ## ##################################
    
    ## creates a direcory based on the name of the script.
    do {
        $scriptFolderTestPath = Test-Path $scriptDirectory\$scriptName -PathType container
        $scriptDocumentFolderTestPath = Test-Path $scriptFolder\$scriptName"_Script_Documents" -PathType container
        $scriptLogFolderTestPath = Test-Path $scriptFolder\$scriptName"_Script_Logs" -PathType container
    
        if ($scriptFolderTestPath -match "False") { 
            $scriptFolder = New-Item $scriptDirectory\$scriptName -ItemType directory
        }
        elseif ($scriptDocumentFolderTestPath -match "False") {
            New-Item $scriptFolder\$scriptName"_Script_Documents" -ItemType directory       
        }
        elseif ($scriptLogFolderTestPath -match "False") {
            New-Item $scriptFolder\$scriptName"_Script_Logs" -ItemType directory
        }
    } Until (($scriptFolderTestPath -match "True") -and ($scriptDocumentFolderTestPath -match "True") -and ($scriptLogFolderTestPath -match "True"))
    
    ## variables for downloading and renaming code.
    $date = (Get-Date -Format yyyy-MM-dd)
    
    ## ################################
    ## begin code for link downloading.
    ## ################################
    
    ## gets contents of the arguement variable.
    $webTargets = Get-Content $linkList
    
    ## downloads the linked file.
    Invoke-WebRequest $webTargets
    

    【讨论】:

    • 它确实抓取了传递的参数并拉动了invoke-webrequest。如果参数有多行添加 'Get-Content $linkList | ForEach-Object { Invoke-WebRequest $_ }' 无论出于何种原因,我都没有正确传递参数,直到阅读该帖子并进行更改。此外,我所有使用 $args 的尝试都未能正常工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-18
    • 2013-10-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多