首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PowerShell模块没有预期的点源/导入功能。

PowerShell模块没有预期的点源/导入功能。
EN

Stack Overflow用户
提问于 2017-07-07 12:38:31
回答 2查看 1.9K关注 0票数 2

Update 1:最初发布的标题是:“脚本忽略PowerShell模块中的错误处理”,因为这是当前的问题,但是看起来更像是模块问题,所以我重新命名了标题。

Update 2:在一条让我对Azure cmdlet产生疑问的评论之后,我使用了最基本的脚本(添加到模块中)进行了测试,结果是相同的,因为错误不会传递给调用脚本,但是,添加-errorVariable to Get-确实返回了一些可能在处理错误时可以利用的东西(WriteErrorException除外):

代码语言:javascript
复制
function Test-MyError($Variable)
{
    Try
    {
        Get-Service -Name $variable -ErrorAction Stop -ErrorVariable bar
        #Get-AzureRmSubscription -SubscriptionName $variable -ErrorAction Stop
    }
    Catch
    {
        Write-Error $error[0]
        $bar
    }
}

返回:

代码语言:javascript
复制
Test-MyError "Foo"

Test-MyError : Exception of type 'Microsoft.PowerShell.Commands.WriteErrorException' was thrown.
At line:3 char:1
+ Test-MyError "Foo"
+ ~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Test-MyError

The running command stopped because the preference variable "ErrorActionPreference" or common parameter is set to Stop: Cannot find any service with service name 'foo'.

但是,如果我在ISE中运行“”,然后调用该函数,我得到:

代码语言:javascript
复制
Test-MyError "Foo"

Test-MyError : Cannot find any service with service name 'Foo'.
At line:3 char:1
+ Test-MyError "Foo"
+ ~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Test-MyError

The running command stopped because the preference variable "ErrorActionPreference" or common parameter is set to Stop: Cannot find any service with service name 'Foo'.

因此,我不知道在ISE中运行“Test”并调用它时会发生什么情况,而不是PSM1文件中的点源,然后调用它?

我现在需要使用-ErrorVariable并处理这个问题吗?

原始问题:,我在一个模块中有两个函数:Get-订阅和Get-AllSubscriptions。每个函数都位于自己的PS1文件和PSM1文件点源中。模块看起来很好,因为使用智能可以访问模块脚本,并且模块没有问题地加载。我在许多模块中都使用过这种结构,而且我以前从未遇到过这个问题。(虽然我不知道MS是否改变了PS5.1中模块的工作方式,正如我注意到的那样,使用FunctionsToExport='x','y','Z'Export-ModuleMember似乎不像以前那样。)

获取-所有订阅电话获得-订阅。

如果我没有登录到Azure,Get订阅应该抛出一个被处理的错误,提示我登录。如果我从Get-Subscription.ps1调用get-Subscription.ps1中的Get-订阅,它就会像预期的那样工作。

但是,当我从一个新的PS1文件、或powershell控制台调用Get-订阅时,它无法工作。它遍历整个do..until循环,而不像我所期望的那样“处理”错误。在每次迭代中,似乎都会抛出一个通用错误:

代码语言:javascript
复制
Get-Subscription : Exception of type 'Microsoft.PowerShell.Commands.WriteErrorException' was thrown.

但是,我确实看到了最后一个错误,Get-Subscription : Unable to find requested subscription after 3 login attempts.

如果我在ISE中执行Get-订阅,然后在一个新的PS1文件中调用Get-订阅,或者从Get-AllSubscriptions调用Get-订阅,那么它就会像预期的那样工作,但是,一旦我重新导入模块(Import-Module AzureVnetTools -Force -Verbose),它就会回到错误的行为。

如果我在调用者脚本中点源获取订阅,它可以工作,但为什么?这就是模块的PSM1应该发生的情况。

有人能帮我找出我在这里做错了什么吗?

(PS 5.1,Windows 7)

Get-Subscription:

代码语言:javascript
复制
function Get-Subscription
{
    [cmdletbinding()]
    Param
    (
        [string]$SubscriptionName,
        [string]$UserName,
        [string]$code
    )

    $c=1
    Write-Verbose "Checking access to '$SubscriptionName' with user '$UserName'..."
    Do
    {
        Write-Verbose "Attempt $c"
        Try
        {
            $oSubscription = Get-AzureRmSubscription -SubscriptionName $SubscriptionName -ErrorAction Stop -WarningAction SilentlyContinue

            Write-Verbose "Subscription found: $($oSubscription.SubscriptionName)."
        }
        Catch
        {
            if($error[0].Exception.Message -like "*Please verify that the subscription exists in this tenant*")
            {
                Write-Verbose "Cannot find subscription '$SubscriptionName' with provided credentials."
                $account = Login-AzureRmAccount -Credential (Get-Credential -UserName $Username -Message "Subscription '$SubscriptionName' user' password:")
            }
            elseif($error[0].Exception.Message -like "*Run Login-AzureRmAccount to login*")
            {
                Write-Verbose "No logged in session found. Please log in."
                $account = Login-AzureRmAccount -Credential (Get-Credential -UserName $Username -Message "Subscription '$SubscriptionName' user' password:")
            }
            else
            {
                Write-Error $error[0]
            }
        }
        $c++
    }
    until(($oSubscription) -or ($c -eq 4))

    if($c -eq 4)
    {
        Write-Error "Unable to find requested subscription after $($c-1) login attempts."
        break
    }
    $oSubscription | Add-Member -MemberType NoteProperty -Name Code -Value $code
    $oSubscription
}

Get-AllSubscriptions:

代码语言:javascript
复制
function Get-AllSubscriptions
{
    [cmdletbinding()]
    param
    (
        [string]$MasterSubscription,
        [string]$MasterSubscriptionCode,
        [string]$MasterSubscriptionUsername,
        [string]$ChildSubscription,
        [string]$ChildSubscriptionCode,
        [string]$ChildSubscriptionUsername
    )

    Write-Verbose "Getting all subscriptions..."

    $oAllSubscriptions = @()

    $oMasterSubscription = Get-Subscription -SubscriptionName $MasterSubscription -UserName $MasterSubscriptionUsername -code $MasterSubscriptionCode -Verbose

    $oChildSubscription = Get-Subscription -SubscriptionName $ChildSubscription -UserName $ChildSubscriptionUsername -code $ChildSubscriptionCode -Verbose

    $oAllSubscriptions = ($oMasterSubscription,$oChildSubscription)
    $oAllSubscriptions

}

测试:

代码语言:javascript
复制
$splat2 = @{
    SubscriptionName = "SomeSubscription"
    Code = "S02"
    Username = "some.user@somewhere.com"
}

#Write-Output "Dot-source:"
#. "D:\Temp\PS.Modules\AzureVnetTools\functions\public\Get-Subscription.ps1"

Get-Subscription @splat2 -verbose

输出:

代码语言:javascript
复制
Get-Subscription @splat2 -verbose
VERBOSE: Checking access to 'SomeSubscription' with user 'some.user@somewhere.com'...
VERBOSE: Attempt 1
Get-Subscription : Exception of type 'Microsoft.PowerShell.Commands.WriteErrorException' was thrown.
At line:7 char:1
+ Get-Subscription @splat2 -verbose
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Get-Subscription

VERBOSE: Attempt 2
Get-Subscription : Exception of type 'Microsoft.PowerShell.Commands.WriteErrorException' was thrown.
At line:7 char:1
+ Get-Subscription @splat2 -verbose
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Get-Subscription

VERBOSE: Attempt 3
Get-Subscription : Exception of type 'Microsoft.PowerShell.Commands.WriteErrorException' was thrown.
At line:7 char:1
+ Get-Subscription @splat2 -verbose
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Get-Subscription

Get-Subscription : Unable to find requested subscription after 3 login attempts.
At line:7 char:1
+ Get-Subscription @splat2 -verbose
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Get-Subscription

AzureVnetTools.psm1

代码语言:javascript
复制
#Get public and private function definition files.
$Public  = @( Get-ChildItem -Path $PSScriptRoot\Functions\Public\*.ps1 -ErrorAction SilentlyContinue )
$Private = @( Get-ChildItem -Path $PSScriptRoot\Functions\Private\*.ps1 -ErrorAction SilentlyContinue )

#Dot source the files
Foreach($import in @($Public + $Private))
{
    #write-error $import.fullname
    Try
    {
        #Write-Host "Dot-sourcing file: $($import.fullname)." 
        . $import.fullname
    }
    Catch
    {
        Write-Error -Message "Failed to import function $($import.fullname): $_"
    }
}

Export-ModuleMember -Function $Public.Basename

AzureVnetTools.psd1 (相关章节):

代码语言:javascript
复制
FunctionsToExport = '*'
EN

回答 2

Stack Overflow用户

发布于 2017-07-07 14:10:54

代码语言:javascript
复制
-ErrorAction Stop -WarningAction SilentlyContinue

它是被抛出而不是错误的警告吗?

票数 0
EN

Stack Overflow用户

发布于 2017-07-28 12:05:00

所以我的具体问题是我依赖于处理错误并在此基础上做一些事情。这个问题是由PowerShell的Write-Error的工作方式(或不工作)引起的,正如我从@Alek给出的答复here中学到的那样。

它只是没有将实际的错误传递回调用脚本。正如@Alex建议的那样,我用$PSCmdlet.WriteError()代替了$PSCmdlet.WriteError()。虽然这并不完全奏效。

Catch{}块中,我将$error[0]更改为$_,并将全部错误返回给调用脚本/函数。

我进一步编写了一个可重用函数,并将其添加到我的模块中:

代码语言:javascript
复制
function Write-PsError
{
    [cmdletbinding()]
    Param
    (
        [Exception]$Message,
        [Management.Automation.ErrorCategory]$ErrorCategory = "NotSpecified"
    )

    $arguments = @(
            $Message
            $null #errorid
            [Management.Automation.ErrorCategory]::$ErrorCategory
            $null

            )

    $ErrorRecord = New-Object -TypeName "Management.Automation.ErrorRecord" -ArgumentList $arguments
    $PSCmdlet.WriteError($ErrorRecord)

}

目前看来效果很好。我特别喜欢intellisense获取所有ErrorCategories的方式。不知道ISE (PS5.1/ Win 7)是如何做到这一点的。我想我必须添加我自己的动态参数。

HTH。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44970992

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档