PowerShell 技能连载 - 获取昨天午夜的日期值

当您了解了每个 DateTime 对象支持 Add...() 方法之后,获取相对日期(例如昨天或下周)就十分容易了。以下代码可以获取昨天的时间值:

$today = Get-Date
$yesterday = $today.AddDays(-1)
$yesterday

$yesterday 的值是当前时间之前 24 小时整的值。那么如果您希望得到昨天特定时刻的值,比如说昨天午夜呢?

如果您希望得到今天午夜的值,那么十分简单:

$todayMidnight = Get-Date -Hour 0 -Minute 0 -Second 0
$todayMidnight

如果您希望得到另一天的该时间值,那么再次使用 Get-Date 来修改时间值。以代码获取昨天午夜的时间值:

$today = Get-Date
$yesterday = $today.AddDays(-1)
$yesterday | Get-Date -Hour 0 -Minute 0 -Second 0

译者注:如果您只是需要获取昨天午夜的日期值,还可以有其它方法。如:(Get-Date).AddDays(-1).Date[System.DateTime]::Today.Subtract([System.TimeSpan]::FromDays(1))

PowerShell 技能连载 - 搜索并观看 PowerShell 视频

PowerShell 是令人惊叹的。它可以根据您选择的关键词搜索 YouTube 视频,然后为您呈现视频,以及根据选择播放视频。

以下这段简单的脚本(需要 Internet 连接)可以列出 YouTube 上最新的“Learn PowerShell”视频。该列表使用一个 Grid View 窗口呈现,您可以在顶部使用全文搜索或者按列排序,来查找您需要的视频。

下一步,单击视频项选中它,然后单击网格右下角的“确定”按钮。

PowerShell 将会启动您的 Web 浏览器并且播放视频。太棒了!

$keyword = "Learn PowerShell"

Invoke-RestMethod -Uri "https://gdata.youtube.com/feeds/api/videos?v=2&q=$($keyword.Replace(' ','+'))" |
Select-Object -Property Title, @{N='Author';E={$_.Author.Name}}, @{N='Link';E={$_.Content.src}}, @{N='Updated';E={[DateTime]$_.Updated}} |
Sort-Object -Property Updated -Descending |
Out-GridView -Title "Select your '$Keyword' video, then click OK to view." -PassThru |
ForEach-Object { Start-Process $_.Link }

只需要改变第一行的 $keyword 变量就可以搜索不同的视频或者主题。

请注意由于 PowerShell 3.0 的一个 bug,Invoke-RestMethod 只会返回一部分结果。PowerShell 4.0 修复了这个 bug。

译者注:由于国内暂时不可直接访问 YouTube 服务,验证本脚本需要合适的代理服务器或 VPN。

PowerShell 技能连载 - 在 Windows 8.1 中管理 Windows Defender

Windows 8.1 发布了一个称为“Defender”的新模块。内置的 cmdlet 使您能够管理、查看和修改 Windows Defender 反病毒程序的每一个方面。

要列出所有可用的 cmdlet,请使用以下代码:

Get-Command -Module Defender

如果您没有获得任何返回信息,那么您正在运行的很可能不是 Windows 8.1,所以该模块不可用。

下一步,试着浏览这些 cmdlet。例如 Get-MpPreference,将列出当前所有偏好设置。类似地,Set-MpPreference 可以改变它们的值。

Get-MpThreatDetection 将会列出当前检测到的所有威胁(如果当前没有任何威胁,则返回空)。

PowerShell 技能连载 - 搜索本地用户

您知道吗?您可以搜索计算机上的本地用户,就像搜索域账户一样。

以下的示例代码搜索所有以“A”开头并且是启用状态的本地用户:

Add-Type -AssemblyName System.DirectoryServices.AccountManagement

$type = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext('Machine', $env:COMPUTERNAME)

$UserPrincipal = New-Object System.DirectoryServices.AccountManagement.UserPrincipal($type)

# adjust your search criteria here:
$UserPrincipal.Name = 'A*'
# you can add even more:
$UserPrincipal.Enabled = $true

$searcher = New-Object System.DirectoryServices.AccountManagement.PrincipalSearcher
$searcher.QueryFilter = $UserPrincipal
$results = $searcher.FindAll();

$results | Select-Object -Property Name, LastLogon, Enabled

类似地,要查找所有设置了密码、密码永不过期,并且是启用状态的本地用户,试试以下代码:

Add-Type -AssemblyName System.DirectoryServices.AccountManagement

$type = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext('Machine', $env:COMPUTERNAME)

$UserPrincipal = New-Object System.DirectoryServices.AccountManagement.UserPrincipal($type)

# adjust your search criteria here:
$UserPrincipal.PasswordNeverExpires = $true
$UserPrincipal.Enabled = $true

$searcher = New-Object System.DirectoryServices.AccountManagement.PrincipalSearcher
$searcher.QueryFilter = $UserPrincipal
$results = $searcher.FindAll();

$results | Select-Object -Property Name, LastLogon, Enabled, PasswordNeverExpires

PowerShell 技能连载 - 获取本地组成员

在 PowerShell 中,通过 .NET Framework 3.51 或更高的版本,可以使用面向对象的方式管理本地用户和组。以下代码可以列出本机上的管理员用户:

Add-Type -AssemblyName System.DirectoryServices.AccountManagement

$type = New-Object DirectoryServices.AccountManagement.PrincipalContext('Machine', `$env:COMPUTERNAME)

$group = [DirectoryServices.AccountManagement.GroupPrincipal]::FindByIdentity($type, `'SAMAccountName', 'Administrators')

$group.Members | Select-Object -Property SAMAccountName, LastPasswordSet, LastLogon, Enabled

您还可以获取更多的信息,比如试着查询组本身的信息:

或者试着列出所有成员的所有属性:

PowerShell 技能连载 - 将 Windows 8.1 中的 CMD.EXE 替换为 POWERSHELL.EXE

Windows 8.1 仍然在它的一些上下文菜单中提供旧的 cmd.exe 命令行窗口。在 Windows 8.1 中,要将它由 cmd.exe 改为 powershell.exe,请右键单击任务栏,然后选择属性。

然后,单击“导航”标签页,然后选中第三个选项。

下一次,当您在 Windows 8.1 中按下 WIN+X 键时,迷你菜单上将显示“PowerShell”。

PowerShell 技能连载 - 使用 PowerShell 管理 Office365

您知道吗?您也可以用 PowerShell 管理您的 Office365 账户。如果您拥有一个 Office365 账户,请试试以下脚本:

$OfficeSession = New-PSSession -ConfigurationName Microsoft.Exchange `-ConnectionUri https://ps.outlook.com/powershell/ -Credential (Get-Credential) `-Authentication Basic -AllowRedirection

$import = Import-PSSession $OfficeSession -Prefix Off365

Get-Command -Noun Off365*

这段代码将使用您的凭据连接 Office 365,然后导入用于管理 Office 365 的 PowerShell cmdlet。您大约可以获得 400 个新的 cmdlet。如果您收到“Access Denied”提示,那么有可能您的账户没有足够的权限,或者您敲错了密码。

注意所有导入的 cmdlet 都是以 Off365 为前缀的,所以要查看所有的邮箱,请试试以下代码:

PS> Get-Off365Mailbox

您可以自己选择前缀(见前面的代码),这样您可以同时通过不同的前缀连接到多个 Office365 账户。当您执行 Import-PSSession 时,您还可以省略前缀。

要查看 Office365 导出的所有命令,请使用以下代码:

$import.ExportedCommands

PowerShell 技能连载 - 显示 Path 环境变量

当您启动一个程序时,$env:Path 环境变量列出了 Windows 搜索路径中的所有目录。类似地,$env:PSModulePath 列出了 PowerShell 搜索 PowerShell 模块(包括它的自动加载模块)的所有目录。

这些变量包含了以分号分隔的信息。所以使用 -split 操作符分隔并显示它们:

顺便说一下,第三行(在 Program Files 中的)是在 PowerShell 4.0 中才加入的。

PowerShell 技能连载 - 查找磁盘分区详细信息

要查看磁盘分区信息,请使用 WMI:

Get-WmiObject -Class Win32_DiskPartition |
  Select-Object -Property *

然后,选择您感兴趣的属性,然后将 * 号替换成逗号分隔的属性列表。例如:

Get-WmiObject -Class Win32_DiskPartition |
  Select-Object -Property Name, BlockSize, Description, BootPartition

如果您选择四个或四个以下的属性,结果是一个干净的表格,否则将是一个列表:

如果您想知道更多的信息,请使用 -List 参数来搜索其它 WMI 类,或者和 “disk” 有关的,或者其它完全不相关的:

PowerShell 技能连载 - 为 AD 用户设置缺省的 Email 地址

编写 Active Directory 脚本不需要额外的 module。通过简单的 .NET 框架方法,您可以实现令人惊叹的功能。实际上,这个技术十分强大,您不应该在您的生产环境下运行以下的例子,除非您知道自己在做什么。

一下代码片段在您的 Active Directory 中查找存储于 CN=Users 并且没有邮箱地址的的所有用户。然后,脚本将为他们设置一个缺省的邮箱地址。该地址由姓名 + “mycompany.com” 组成。

# adjust LDAP path (i.e. remove CN=Users to search the entire domain):
$SearchRoot = 'LDAP://CN=Users,{0}' -f ([ADSI]'').distinguishedName.ToString()
# adjust LDAPFilter. Example: (!mail=*) = all users with no defined mail attribute
$LdapFilter = "(&(objectClass=user)(objectCategory=person)(!mail=*))"

$Searcher = New-Object DirectoryServices.DirectorySearcher($SearchRoot, $LdapFilter)
$Searcher.PageSize = 1000
$Searcher.FindAll() | ForEach-Object {
  $User = $_.GetDirectoryEntry()
  try
  {
        # Set mail attribute
        $User.Put("mail", ('{0}.{1}@mycompany.com' -f $user.givenName.ToString(), $user.sn.ToString()))

        # Commit the change
        $User.SetInfo()
  }
  catch { Write-Warning "Problems with $user. Reason: $_" }
}

这个示例代码可以读取并且修改、设置任意的属性。它特别适用于不能通过 cmdlet 设置的自定义属性。