首页 > 解决方案 > 如何使 Powershell Invoke-WebRequests 脚本以交互方式传递 Where-Object 字符串中的变量

问题描述

所以我有两个在 Powershell 1903 Update 中运行的脚本。当我在 Where-Object {} 字符串中传递变量时,其中一项工作失败。

工作脚本将下载下载目录中的文件

#!/bin/powershell
# ====================================================================================================
# Author: Richard Barrett
# Organization: Del Valle ISD
# Date: 12/04/2019
# Purpose: To Add an Interactive Script within Powershell for Windows Users to Download multiple Links
# ====================================================================================================

# ==============================================================================================
#         Documentation
# ==============================================================================================
# https://www.gngrninja.com/script-ninja/2016/7/8/powershell-getting-started-utilizing-the-web

# ==============================================================================================

# Interactive Authentication && Interactively Establish Target Links
# ==================================================================
# Add in Information that makes the link as an interactive question
# Add in  Authentication Question and make the authentication session interactive
#$DownloadLink = Read-Host -Prompt 'Input the link you would like to download from'
#$Authentication = Read-Host -Prompt 'Does the site you want to download from require authentication Y/n'
#$Username = Read-H
#$Password
#$Date = Get-Date


$downloadURL     = 'https://www.tukui.org/welcome.php'
$downloadRequest = Invoke-WebRequest -Uri $downloadURL
$downloadRequest

# ==================================================================

# Interactively Query for Permission to Download and Save Path
# Add in Would you like to See All Download Links?

# Define the http:/ and https:/ variables
# =======================================
#$http  = echo 'http:/'
#$https = echo 'https:/'

#$downloadRequest.Links

# Add in Interactivity question where you define the parser variable based on download.
$downloadRequest.Links | Where-Object {$_ -like '*elv*' -and $_ -like '*download*'}
$elvLink = ($downloadRequest.Links | Where-Object {$_ -like '*elv*' -and $_ -like '*download*'}).href | Select -Last 1

echo "This is the suffix link, would you like to add http:// or https://?"
$elvLink

$Link = ($downloadURL + $elvLink)
$Link

# Add in Exit code for HTTP and HTTPS Based Downloads
# Write the file to the ".\Downloads\" Directory
# ====================================================
$fileName        = $Link.Substring($Link.LastIndexOf('/')+1)
$downloadRequest = Invoke-WebRequest -Uri $Link
$fileContents    = $downloadRequest.Content
$downloadRequest  =  Invoke-WebRequest -Uri $Link -OutFile "C:\Users\richard.barrett\Downloads\$fileName" -PassThru
#EOF

所以这很有效,我试图清理它并使其更具交互性。您可以在以下脚本中看到更改

#!/bin/powershell
# ====================================================================================================
# Author: Richard Barrett
# Organization: Del Valle ISD
# Date: 12/04/2019
# Purpose: To Add an Interactive Script within Powershell for Windows Users to Download multiple Links
# ====================================================================================================

# ==============================================================================================
#         Documentation
# ==============================================================================================
# https://www.gngrninja.com/script-ninja/2016/7/8/powershell-getting-started-utilizing-the-web

# ==============================================================================================

# Interactive Authentication && Interactively Establish Target Links
# ==================================================================
# Add in Information that makes the link as an interactive question
# Add in  Authentication Question and make the authentication session interactive
echo 'Notes: You can use the following information for testing purposes for the following variables'
echo 'xxxxx: For DownloadLink use https://www.tukui.org/welcome.php'
echo 'xxxxx: For Parservariable use elv'
echo 'xxxxx: For ActionVariable use download'
echo '=================================================================================================================='
$DownloadLink           = Read-Host -Prompt 'Input the link you would like to download from for variable DownloadLink'
$Authentication         = Read-Host -Prompt 'Does the site you want to download from require authentication [Y/y]/[N/n]'
$Username               = Read-Host -Prompt 'Enter in your Username for the Website you want to pull from'
$Password               = Read-Host -Prompt 'Enter in the password assigned to the above entered Username'
$Date                   = Get-Date

$downloadURL            = $DownloadLink
$downloadRequest        = Invoke-WebRequest -Uri $downloadURL
$downloadRequest

# Interactively Query for Permission to Download and Save Path
# Add in Would you like to See All Download Links?
#$downloadRequest.Links

# Set Parser Variable
$ParserVariable = Read-Host -Prompt 'What Parser would you like to use for variable ParserVariable?'
$ActionVariable = Read-Host -Prompt 'What action would you like to do [Download/Share] for variable ActionVariable?'
$downloadRequest.Links | Where-Object {$_ -like '*$ParserVariable*' -and $_ -like '*$ActionVariable*'}
$PackageLink    = ($downloadRequest.Links | Where-Object {$_ -like '*$ParserVariable*' -and $_ -like '*ActionVariable*'}).href | Select -Last 1

$Transport      = Read-Host -Prompt 'This is the suffix link, which transport method should be used [http:// or https://]?'
$PackageLink

$Validation     = Read-Host -Prompt 'Does the link from the above PackageLink look to be the correct format?'
$Link           = ($downloadURL + $PackageLink)
$Link

# Add in Exit code for HTTP and HTTPS Based Downloads
# Write the file to the ".\Downloads\" Directory
# ====================================================
$fileName               = $Link.Substring($Link.LastIndexOf('/')+1)
$downloadRequest        = Invoke-WebRequest -Uri $Link
$fileContents           = $downloadRequest.Content
$downloadRequest        = Invoke-WebRequest -Uri $Link -OutFile "C:\Users\richard.barrett\Downloads\$fileName" -PassThru
#EOF

我遇到的主要问题是我想让解析更具交互性并从$downloadRequests.Links.

代码作品:

$downloadRequest.Links | Where-Object {$_ -like '*elv*' -and $_ -like '*download*'}
$elvLink = ($downloadRequest.Links | Where-Object {$_ -like '*elv*' -and $_ -like '*download*'}).href | Select -Last 1

echo "This is the suffix link, would you like to add http:// or https://?"
$elvLink

$Link = ($downloadURL + $elvLink)
$Link

代码失败

$ParserVariable = Read-Host -Prompt 'What Parser would you like to use for variable ParserVariable?'
$ActionVariable = Read-Host -Prompt 'What action would you like to do [Download/Share] for variable ActionVariable?'
$downloadRequest.Links | Where-Object {$_ -like '*$ParserVariable*' -and $_ -like '*$ActionVariable*'}
$PackageLink    = ($downloadRequest.Links | Where-Object {$_ -like '*$ParserVariable*' -and $_ -like '*ActionVariable*'}).href | Select -Last 1

在调试代码时,我得到了以下输出。

PS C:\Users\richard.barrett\Projects\Powershell\Training\Invoke-WebRequests> $downloadRequest.Links | Where-Object {$_ -like '*'$ParserVariable'*' -and $_ -like '*'$ActionVariable'*'}                                                                   At line:1 char:52
+ ... dRequest.Links | Where-Object {$_ -like '*'$ParserVariable'*' -and $_ ...
+                                                ~~~~~~~~~~~~~~~~~~
Unexpected token '$ParserVariable'*'' in expression or statement.
At line:1 char:67
+ ... dRequest.Links | Where-Object {$_ -like '*'$ParserVariable'*' -and $_ ...
+                                                               ~~~
Unexpected token ''*'' in expression or statement.
At line:1 char:88
+ ...  {$_ -like '*'$ParserVariable'*' -and $_ -like '*'$ActionVariable'*'}
+                                                       ~~~~~~~~~~~~~~~~~~
Unexpected token '$ActionVariable'*'' in expression or statement.
At line:1 char:103
+ ...  {$_ -like '*'$ParserVariable'*' -and $_ -like '*'$ActionVariable'*'}
+                                                                      ~~~
Unexpected token ''*'' in expression or statement.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : UnexpectedToken

PS C:\Users\richard.barrett\Projects\Powershell\Training\Invoke-WebRequests> $downloadRequest.Links | Where-Object {$_ -like '*elv*' -and $_ -like '*download*'}                                                                                          

innerHTML : &nbsp;<SPAN class=font-menu>Download (Retail)</SPAN>
innerText :  Download (Retail)
outerHTML : <A class="fa fa-download" href="/download.php?ui=elvui">&nbsp;<SPAN class=font-menu>Download (Retail)</SPAN></A>
outerText :  Download (Retail)
tagName   : A
class     : fa fa-download
href      : /download.php?ui=elvui

innerHTML : &nbsp;<SPAN class=font-menu>Changelog</SPAN>
innerText :  Changelog
outerHTML : <A class="fa  fa-file-text-o" href="/download.php?ui=elvui&amp;changelog">&nbsp;<SPAN
            class=font-menu>Changelog</SPAN></A>
outerText :  Changelog
tagName   : A
class     : fa  fa-file-text-o
href      : /download.php?ui=elvui&amp;changelog

innerHTML : Download ElvUI <SPAN class=hidden-xs>11.25</SPAN>
innerText : Download ElvUI 11.25
outerHTML : <A class="btn btn-mod btn-border-w btn-small btn-round" href="/downloads/elvui-11.25.zip">Download ElvUI <SPAN
            class=hidden-xs>11.25</SPAN> </A>
outerText : Download ElvUI 11.25
tagName   : A
class     : btn btn-mod btn-border-w btn-small btn-round
href      : /downloads/elvui-11.25.zip

任何帮助都将不胜感激,因为我比其他任何东西都更熟悉 Linux,目前我正在尝试自动化多个下载文件,所以我真的只是使用它作为模板来自动化一些下载到本地服务器。我知道我可以使用 python,但我有点想同时了解更多关于 Powershell 的知识。

好心,理查德

标签: windowspowershell

解决方案


就像@Alex_P 在他的评论中所说,使用单引号将使其成为字符串文字。使用双引号,以便 PowerShell 使用变量。

另外,如果您确定要使用*通配符,那么建议使用它,-like因为它主要用于通配符比较。否则,-match用于正则表达式。

$ParserVariable = Read-Host -Prompt "What Parser would you like to use for variable ParserVariable?"
$ActionVariable = Read-Host -Prompt "What action would you like to do [Download/Share] for variable ActionVariable?"
$downloadRequest.Links | Where-Object {$_ -like "*$ParserVariable*" -and $_ -like "*$ActionVariable*"}
$PackageLink    = ($downloadRequest.Links | Where-Object {$_ -like "*$ParserVariable*" -and $_ -like "*ActionVariable*"}).href | Select -Last 1

此外,通配符是正则表达式的子集,因此可以在-match. 与最适合性能的字符串方法-like相比,您将获得更好的性能。需要注意的是,该方法只会返回一个布尔值。-match.contains('some_string').contains()


推荐阅读