【问题标题】:Powershell: How to throw an error if a CSV entry is blankPowershell:如果 CSV 条目为空,如何引发错误
【发布时间】:2015-10-28 12:15:45
【问题描述】:

我编写了一个运行 AD 终止过程的扩展脚本,该脚本可以从 CSV 中获取必要的信息。如果 CSV 中的条目为空白,我该如何制作它以使其出错?我尝试使用 Try-Catch、If-Else 以及我知道如何做的所有事情。我已经尝试更改错误操作,我可以让它抛出系统生成的错误(例如“无法将参数“身份”绑定到目标......”),但我无法让它做我想做的事。请看下面的代码示例:

(是的,我知道我在重复值。这在脚本后面很重要,而不是我遇到问题的部分)

    $owner = $user.'Network User ID'}
    $loginID = $user.'Network User ID'
    $Identity = Get-ADUser -Identity $owner -Properties Displayname |Select-Object -ExpandProperty Displayname 
    $manager = $user.'Provide Inbox Access To'
    $NewOwner = $user.'Provide users email group ownership to'
    $NewOwnerID = $User.'Provide users email group ownership To'

如果 CSV 中的任何条目为空白,我需要它做的是抛出一个错误,然后终止。我尝试过的最有希望的想法是:

    If ($Owner -eq $Null)
    {
    Write-Host "Invalid entry, the Network User ID field cannot be blank"
    Write-Host "Press Enter to Exit..."
    Exit
    }
    Else
    {
    #Do everything else
    }

但即使这样仍然失败。

总之,如果 CSV 中的条目为空白,我需要做的是引发自定义终止错误。

非常感谢任何帮助!

编辑

如果有帮助,这里有更多真实代码...

$Confirmation = Read-Host "Please double check the information in the file. Are you sure you want to continue? (Y/N)"

If($Confirmation -eq "Y")
{
Write-Host "You have chosen to proceed. Processing Termination" -BackgroundColor DarkCyan
#Import file
$file = "C:\TerminateUsers.csv"
$data = Import-Csv $file
#Set disabled OU
$disabledOU = "OU=Users,OU=Disabled Accounts, OU=Corporate"

$colOutput = @()
foreach ($user in $data)
{
    #Grab variables from CSV
    $owner = $user.'Terminated Network User ID'}
    $loginID = $user.'Terminated Network User ID'

    #Displayname required for Outlook functions
    $Identity = Get-ADUser -Identity $owner -Properties Displayname |Select-Object -ExpandProperty Displayname 
    $manager = $user.'Provide Inbox Access To'
    $NewOwner = $user.'Provide users email group ownership to'
    $NewOwnerID = $User.'Provide users email group ownership To'
    If (Get-ADUser -LDAPFilter "(sAMAccountName=$loginID)")
        {
        $date = Get-Date -Format d
        #Disable account, change description, disable dialin, remove group memberships
        Set-ADUser -Identity $loginID -Enabled $false
        Set-ADUser -Identity $loginID -Replace @{Description = "Terminated $date"}
        Set-ADUser -Identity $loginID -Replace @{msNPAllowDialin = $False}
        RemoveMemberships $loginID 

这还不是全部,但这是我们正在处理的部分......

【问题讨论】:

  • 我还想指出,我已经尝试只运行 if-else 和 try-catch 语句而没有脚本的其余部分,只需在单独的选项卡中运行该块即可。这仍然根本不起作用。

标签: csv powershell if-statement try-catch custom-error-handling


【解决方案1】:

你会在这里遇到很多问题。

首先,$Owner -eq $Null 不会做你想做的事。主要问题是空字符串不是空值。他们是不同的。相反,您的测试应该是:

if ([string]::IsNullOrEmpty($owner)) { ... }

或者:

if ([string]::IsNullOrWhiteSpace($owner)) { ... }

如果字符串仅包含制表符、空格或其他空白字符,或者是空字符串,或者为 null,则第二个返回 true。

其次,要抛出异常,需要使用throw关键字。见Get-Help about_Throw。例如:

if ([string]::IsNullOrWhiteSpace($owner)) {
    throw "Owner is null or empty.";
}

如果您将此嵌入到 try 块中,则可以使用关联的 catch 块捕获异常。见Get-Help about_Try_Catch_Finally。你也可以使用Trap,我相信(见Get-Help about_Trap)。

最后,遇到错误时的默认操作由$ErrorActionPreference 变量控制。该变量的默认值为Continue,因此将显示错误消息,但脚本将继续执行,就好像根本没有发生错误一样。我不完全确定这如何与手动抛出的异常和 try/catch 块一起工作,但除非我知道我希望我的脚本忽略错误,否则我几乎从每个脚本开始:

$ErrorActionPreference = Stop;

请参阅 Get-Help about_Preference_VariablesGet-Help about_CommonParameters 了解有关此的更多信息。

【讨论】:

  • 我可能理解错了这个问题,但他问:如果 CSV 中的任何条目为空白,我需要它做的是抛出错误,然后终止。这只有在您单独检查每一列时才有效,不是吗?
  • @Matt Hm,我同意,但我想我对脚本的解释不同。我假设在 sn-p 之前有一个 foreach ($user in $myCsvFile) { ...
  • 我添加了更多我正在使用的代码块,希望它能帮助您更好地理解我在做什么。谢谢!
【解决方案2】:

考虑以下数据集。请注意其中一列的 Last_Name 为空。

user_name  first_name last_name
---------  ---------- ---------
lrivera0   Lawrence   Rivera   
tlawrence1 Theresa    Lawrence 
rboyd2     Roy                 
cperry3    Christine  Perry    
jmartin4   Jessica    Martin  

因此,如果我们想确保只处理完整的行,那么一个简单的If 就可以解决这个问题。

Import-Csv .\text.csv | ForEach-Object{
  If($_.Psobject.Properties.Value -contains ""){
     # There is a null here somewhere
     Throw "Null encountered. Stopping"
  } else {
    # process as normal
  }
}

问题是Import-CSV 将空值视为零长度字符串。我尝试仅在$_ 上使用-contains,但它不起作用,因为$_ 不是数组而是具有属性的对象。所以我使用对象属性value 来进行比较。

Bacon 提出了一个有趣的观点,即该代码不会仅考虑空白值。

我们使用throw,因此如果遇到空值,处理将停止。使用该 if 块,您可以执行任何您想要的操作。

【讨论】:

  • Import-CSV .\text.csv | %{$_.psobject.Properties|?{$_.Name -eq 'values'}|Select -expand value|?{$_ -match "^\s*$"}|%{Throw "Null encountered. Stopping";Exit}} - 检查每个记录的每个属性的每个值是否为空或空格,如果发现任何值,则会引发错误并退出。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-06
  • 1970-01-01
  • 2023-03-14
相关资源
最近更新 更多