PowerShell 技能连载 - 查找过期的证书

PowerShell 通过 cert: 驱动器来存取您的证书存储。

您可以根据指定的规则用这个驱动器来查找证书。以下代码将列出所有 NotAfter 字段中有值并在今日之前(意味着证书已过期)的证书:

$today = Get-Date

Get-ChildItem -Path cert:\ -Recurse |
  Where-Object { $_.NotAfter -ne $null  } |
  Where-Object { $_.NotAfter -lt $today } |
  Select-Object -Property FriendlyName, NotAfter, PSParentPath, Thumbprint |
  Out-GridView

PowerShell 技能连载 - 传递参数给 EXE 文件

从 PowerShell 运行某些应用程序,例如 robocopy.exe 不是很方便。如何向 EXE 传递参数,并且确保通过 PowerShell 不会传错值呢?

方法很简单:确保所有的参数是字符串(所以如果参数不是字符串或包含其它特殊字符,那么用双引号把它们包起来)。并且,确保针对每个参数提交一个字符串,而不是单个大字符串。

以下代码将从 PowerShell 执行 robocopy.exe 并且递归地从 Windows 文件夹中拷贝所有的 JPG 图片到另一个 c:\jpegs 文件夹中,遇到错误不重试,并跳过 winsxs 文件夹。

$arguments = "$env:windir\", 'c:\jpegs\','*.jpg', '/R:0', '/S', '/XD', '*winsxs*'

Robocopy.exe $arguments

如您所见,所有的参数都是字符串,并且它们都以一个字符串数组的形式传递。

这种方法完美地运行于所有您希望通过 PowerShell 调用的 exe 程序。

用一句话定义 PowerShell

摘要:微软脚本小子 Ed Wilson,提供了对 Windows PowerShell 的一句话描述,并且证明了它不超过 30 个单词。

问:如何用一句话定义 Windows PowerShell?

答:Windows PowerShell 是微软公司开发的下一代命令行和脚本语言,它在多数环境下可以替代 vbscript 和 cmd 命令行。

问:您如何确定这句话不超过 30 个单词?

答:用以下代码:

$a = "Windows PowerShell is the next generation cmd prompt and scripting language from Microsoft. It can be a replacement for vbscript and for the cmd prompt in most circumstances."

Measure-Object -InputObject $a -Word

原文:

PowerTip: Define PowerShell in Thirty Words or Less

Summary: Microsoft Scripting Guy, Ed Wilson, offers a quick thirty-word description of Windows PowerShell, and he proves it.

Q: What is Windows PowerShell in thirty words or less?

A: Windows PowerShell is the next generation cmd prompt and scripting language from Microsoft. It can be a replacement for vbscript and for the cmd prompt in most circumstances.

Q: How can you be sure that was thirty words or less?

A: By using the following code:

$a = "Windows PowerShell is the next generation cmd prompt and scripting language from Microsoft. It can be a replacement for vbscript and for the cmd prompt in most circumstances."

Measure-Object -InputObject $a -Word

本文国际来源

PowerShell 技能连载 - 应用 NTFS 存取权限

有很多方法可以增加或修改 NTFS 权限。其中一个方法是复用现成的工具,例如 icacls.exe

这个函数将以缺省权限创建新的文件夹。该脚本使用 icacls.exe 来显式地为当前用户添加完全权限以及为本地管理员添加读取权限:

function New-Folder
{
  param
  (
    [String]
    $path,

    [String]
    $username = "$env:userdomain\$env:username"
  )

  If ( (Test-Path -Path $path) -eq $false )
  {
    New-Item $path -Type Directory | Out-Null
  }

  icacls $path /inheritance:r /grant '*S-1-5-32-544:(OI)(CI)R' ('{0}:(OI)(CI)F' -f $username)
}

PowerShell 技能连载 - 获取系统信息

如果您只是需要获取本地系统或远程系统的常见配置信息,那么不必浪费时间去研究自己的解决方案。只需要使用 systeminfo.exe,然后将数据导入 PowerShell:

function Get-SystemInfo
{
  param($ComputerName = $env:COMPUTERNAME)

  $header = 'Hostname','OSName','OSVersion','OSManufacturer','OSConfiguration','OS Build Type','RegisteredOwner','RegisteredOrganization','Product ID','Original Install Date','System Boot Time','System Manufacturer','System Model','System Type','Processor(s)','BIOS Version','Windows Directory','System Directory','Boot Device','System Locale','Input Locale','Time Zone','Total Physical Memory','Available Physical Memory','Virtual Memory: Max Size','Virtual Memory: Available','Virtual Memory: In Use','Page File Location(s)','Domain','Logon Server','Hotfix(s)','Network Card(s)'

  systeminfo.exe /FO CSV /S $ComputerName |
    Select-Object -Skip 1 |
    ConvertFrom-CSV -Header $header
}

以下是结果:

如果把结果保存到一个变量,您可以很容易地独立存取里面的每一条信息:

如果您想用别的名字来获取信息,只需根据需要改变属性名列表。例如您不喜欢“System Boot Time”,那么只需要在脚本中将它重命名为“BootTime”。

PowerShell 技能连载 - 在 PowerShell 中提升命令权限

有些时候,一个脚本需要运行一个需提升(管理员)权限的命令。

一种方法是将用管理员权限运行整个脚本,另一种方法是将独立的命令送到提升权限的 shell 中执行。

这段代码将重启 Spooler 服务(需要提升权限),并将命令发送到另一个 PowerShell 进程中。如果当前进程没有管理员权限,它将自动提升权限。

$command = 'Restart-Service -Name spooler'
Start-Process -FilePath powershell.exe -ArgumentList "-noprofile -command $Command" `
-Verb runas

PowerShell 技能连载 - 获取无线网卡

在上一个技巧中,我们演示了如何使用注册表信息来查找无线网卡。以下是一个可以返回您系统中所有无线网卡的 Get-WirelessAdapter 函数:

function Get-WirelessAdapter
{
  Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Network\*\*\Connection' -ErrorAction SilentlyContinue |
    Select-Object -Property MediaSubType, PNPInstanceID |
    Where-Object { $_.MediaSubType -eq 2 -and $_.PnpInstanceID } |
    Select-Object -ExpandProperty PnpInstanceID |
    ForEach-Object {
      $wmipnpID = $_.Replace('\', '\\')
      Get-WmiObject -Class Win32_NetworkAdapter -Filter "PNPDeviceID='$wmipnpID'"
    }
}

只需要运行该函数:

由于该函数返回一个 WMI 对象,所以您可以获知该网卡当前是否是活动的,或者启用禁用它。

以下代码将取出网卡对象,然后禁用它,再启用它:

$adapter = Get-WirelessAdapter
$adapter.Disable().ReturnValue
$adapter.Enable().ReturnValue

请注意返回值 5 意味着您没有足够的权限。请以管理员身份运行该脚本。

PowerShell 技能连载 - 查找无线网卡

有很多方法可以查找网卡,但似乎没有办法识别活动的无线网卡。

您网卡的所有信息都可以在注册表中找到,以下是一个单行的代码,可以提供您想要的信息:

有趣的部分是 MediaSubType 值。无线网卡的 MediaSubType 值总是 2。

所以这行代码只返回无线网卡:

PowerShell 技能连载 - 以 GB 和百分比的形式显示驱动器容量

当一个 cmdlet 返回原始数据时,您可能希望将数据转换为一个更好的格式。例如,WMI 可以汇报驱动器的剩余空间,但是是以字节为单位的。

您可以使用 Select-Object 并且传入一个哈希表来将原始数据转换为您希望的格式。这个例子演示了如何将剩余空间转换为以 GB 为单位,并且计算剩余空间的百分比:

$Freespace =
@{
  Expression = {[int]($_.Freespace/1GB)}
  Name = 'Free Space (GB)'
}

$PercentFree =
@{
  Expression = {[int]($_.Freespace*100/$_.Size)}
  Name = 'Free (%)'
}

Get-WmiObject -Class Win32_LogicalDisk |
  Select-Object -Property DeviceID, VolumeName, $Freespace, $PercentFree

以下是不使用哈希表的结果:

这是使用了哈希表的结果:

PowerShell 技能连载 - 查找空闲容量低的硬盘驱动器

可以通过 WMI 轻松地获取驱动器信息。以下代码可以从您的本地计算机中获取驱动器信息(用 -ComputerName 可以存取远程系统的信息)。

要限制结果只包含硬盘驱动器,并且只包含空闲容量低于指定值的硬盘驱动器,请试试以下代码:

$limit = 80GB
Get-WmiObject -Class Win32_LogicalDisk -Filter "DriveType=3 and Freespace<$limit" |
  Select-Object -Property VolumeName, Freespace, DeviceID