【问题标题】:Can this powershell script be made as a one-liner?这个powershell脚本可以做成单行吗?
【发布时间】:2018-09-05 21:51:08
【问题描述】:

如题,这段“剧本”能做成单行吗?最好不要分号。

为什么?只是为了其中的乐趣和教育部分完全

$mbx=get-mailbox "a mailbox"
$calendar=$($mbx.PrimarySmtpAddress.toString()) + ":\" + (Get-MailboxFolderStatistics $mbx.PrimarySmtpAddress.toString() | Where-Object { $_.Foldertype -eq 'Calendar' } | Select-Object -First 1).Name
$var=Get-MailboxFolderPermission -Identity $calendar -ErrorAction SilentlyContinue | select-object @{Label="Identity";expression={$mbx.Alias}},FolderName,User,AccessRights
$var.Foreach({ if ($_.User.DisplayName -eq 'Test') { $_.User.DisplayName }})

我到达的最近的是 3 行:

$mbx=get-mailbox "a mailbox"
$Perm=Get-MailboxFolderPermission -Identity $($mbx.PrimarySmtpAddress.toString() + ":\" + (Get-MailboxFolderStatistics $mbx.PrimarySmtpAddress.toString() | Where-Object { $_.Foldertype -eq 'Calendar' } | Select-Object -First 1).Name) | Select-Object @{Label="Identity";expression={$mbx.Alias}},FolderName,User,AccessRights
$Perm.Foreach({ if ($_.User.DisplayName -eq 'Test') { $_.User.DisplayName }})

编辑:

我靠近了几步,但这需要输入两次邮箱。

@(Get-MailboxFolderPermission -Identity $($(Get-Mailbox "a mailbox" | select-Object -ExpandProperty PrimarySmtpAddress).toString() + ":\" + (Get-MailboxFolderStatistics $(Get-Mailbox "a mailbox" | select-Object -ExpandProperty PrimarySmtpAddress).toString() | Where-Object { $_.Foldertype -eq 'Calendar' } | Select-Object -First 1).Name)).Foreach({ if ($_.User.DisplayName -eq 'Test') { $_.User.DisplayName }})

【问题讨论】:

  • 任何东西都可以是带有足够分号的单行...
  • 我了解整个教育方面,但请不要沉迷于单行。总是,总是选择代码的可读性和可维护性而不是“聪明”。
  • @boxdog 我从来没有提到单线是正确的,但我确实提到它是为了它的乐趣和教育部分。 ;)
  • 如果这是你想做的事情,那就去学习 Perl...foo.be/docs/tpj/issues/vol3_2/tpj0302-0012.html
  • 空白是编写无人能维护的代码的好地方en.wikipedia.org/wiki/Whitespace_(programming_language)

标签: powershell scripting office365 exchange-server


【解决方案1】:

这可能有效(PSv4+;单个语句也可用作单行):

(Get-MailboxFolderPermission -Identity (
  ($mbx=Get-Mailbox 'a mailbox').PrimarySmtpAddress.ToString() + ":\" +                      #" 
   (Get-MailboxFolderStatistics $mbx.PrimarySmtpAddress.ToString()).
     Where({$_.FolderType -eq 'Calendar'}, 'First').Name
 ) | Select-Object @{Label='Identity';expression={$mbx.Alias}},FolderName,User,AccessRights
).Where({ $_.User.DisplayName -eq 'Test' })

请注意Get-MailboxFolderStatistics,即使它需要一个邮箱参数,也不会直接接受存储在$mbx 中的[Microsoft.Exchange.Data.Directory.Management.Mailbox] 实例,因此需要$mbx.PrimarySmtpAddress.ToString();谢谢,NiklasJ

简洁可以很优雅,但很容易混淆,尤其是过长的行。

以上是针对前者的,使用跨多行的单个语句,缩进澄清结构。

  • 请注意,由于换行符的放置方式,不需要使用` 续行。

  • 注意$mbx 是如何早期在表达式中分配并在稍后在命令中重用的。

  • 注意 PSv4+ 集合运算符 .Where(...) 与模式参数 First 的使用,这是 | Where-Object ... | Select-Object -First 1 的更有效替代方法

  • 该命令的输出是所有使用Select-Object 创建的对象,其.User.DisplayName 的值是字符串Test

    • 要实现原始命令的输出,您只需要附加 .User.DisplayName,但请注意,这只会输出任意数量的 Test 字符串实例(或其大小写变体),而无需进一步的上下文。

【讨论】:

    【解决方案2】:
    $mbx=get-mailbox "a mailbox"; $Perm=Get-MailboxFolderPermission -Identity $($mbx.PrimarySmtpAddress.toString() + ":\" + (Get-MailboxFolderStatistics $mbx.PrimarySmtpAddress.toString() | Where-Object { $_.Foldertype -eq 'Calendar' } | Select-Object -First 1).Name) | Select-Object @{Label="Identity";expression={$mbx.Alias}},FolderName,User,AccessRights; $Perm.Foreach({ if ($_.User.DisplayName -eq 'Test') { $_.User.DisplayName }})
    

    【讨论】:

    • 分号并不是我真正想要的。任何脚本都可以用分号分隔成一行。
    • 因为你有嵌套的进程块,你必须在某些时候使用分号。这只是最简单的方法。
    【解决方案3】:

    在我看来,显而易见的答案是创建一个函数:

    Function Start-OneLiner
    {
        Param
        (
            [String]
            $Name
        )
        $mbx=Get-Mailbox $Name
        $calendar=$($mbx.PrimarySmtpAddress.toString()) + ":\" + (Get-MailboxFolderStatistics $mbx.PrimarySmtpAddress.toString() | Where-Object { $_.Foldertype -eq 'Calendar' } | Select-Object -First 1).Name
        $var=Get-MailboxFolderPermission -Identity $calendar -ErrorAction SilentlyContinue | select-object @{Label="Identity";expression={$mbx.Alias}},FolderName,User,AccessRights
        $var.Foreach({ if ($_.User.DisplayName -eq 'Test') { $_.User.DisplayName }})
    }
    

    函数可以是来自.ps1 文件的dot sourced,也可以是来自creating a moduleautomatically loaded(Powershell 3.0 和更高版本)。

    您的一个班轮将是:

    Start-OneLiner -name a mailbox
    

    【讨论】:

      【解决方案4】:

      我找到了另一种可行的解决方案,它是 mklement0's answer 的模型,但有选择地定义了收集哪些子属性,然后将特定值解析到查询中。

      单线:

      (Get-MailboxFolderPermission -Identity ( ( $mbx=(Get-Mailbox 'a mailbox' | select-object Identity,PrimarySmtpAddress,Alias) ).PrimarySmtpAddress.ToString() + ":\" + ((Get-MailboxFolderStatistics $mbx.Identity).Where{$_.FolderType -eq 'Calendar'}|Select-Object -First 1).Name )| Select-Object @{Label='Identity';expression={$mbx.Alias}},FolderName,User,AccessRights).Where({ $_.User.DisplayName -eq 'Test' })
      

      可读:

      (
          Get-MailboxFolderPermission -Identity ( 
              ( $mbx=(Get-Mailbox 'a mailbox' | select-object Identity,PrimarySmtpAddress,Alias) ).PrimarySmtpAddress.ToString() + ":\" +                 #"
              (
                  (Get-MailboxFolderStatistics $mbx.Identity).Where{
                      $_.FolderType -eq 'Calendar'
                  }
                  |Select-Object -First 1
              ).Name
          )
          | Select-Object @{Label='Identity';expression={$mbx.Alias}},FolderName,User,AccessRights
      ).Where(
          { $_.User.DisplayName -eq 'Test' }
      )
      

      【讨论】:

        猜你喜欢
        • 2021-12-05
        • 2019-04-21
        • 1970-01-01
        • 2017-09-02
        • 2017-11-06
        • 2011-05-13
        • 2023-04-03
        • 1970-01-01
        • 2012-04-23
        相关资源
        最近更新 更多