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” 有关的,或者其它完全不相关的:

手动控制 VMware 服务

VMware Workstation 想必是很多朋友的必装软件,强大的虚拟机功能已经不用多解释了。这里提点小小的内存优化建议,就是我们在安装完 VMware Workstation 之后,它默认是开机自启动的。那有人会说,打开msconfig,在启动项里将它关闭不就行了吗?其实不然,VMware的几个进程都是以服务方式启动的,vmware-authd.exe、vmnetdhcp.exe、vmnat.exe等等,如不经处理,它们会常驻在系统内存中。而我们并不是每天都会使用虚拟机,所以那些进程大部分时间是在浪费我们的系统资源。

但如果在服务里面将它们全部禁用,那么 VMware 也就不能使用了。最好的方法就是打开服务管理器,将它的几个服务项先全部右击停止,然后双击进去,在启动类型中改为“手动”。这样一来,开机就不会自动启动了。那么,要开 VMware 的时候怎么办呢?一个个手工开启?没必要,写个 PowerShell 脚本就可以了,我用的是最新版VMware Workstation 10,代码如下:

将所有 VMware 服务设置为手动:

# Set-VMWareServiceToManual.ps1
Get-Service -DisplayName vmware* | % {
    Set-Service -Name $_.Name -StartupType Manual
}

将所有 VMware 服务设置为自动(缺省):

# Set-VMWareServiceToAuto.ps1
Get-Service -DisplayName vmware* | % {
    Set-Service -Name $_.Name -StartupType Automatic
}

启动所有 VMware 服务(准备运行 VMware 的时候):

# Start-VMWareService.ps1
Get-Service -DisplayName vmware* | % {
    Start-Service -Name $_.Name
}

停止所有 VMware 服务(运行 VMware 完毕以后):

# Stop-VMWareService.ps1
Get-Service -DisplayName vmware* | % {
    Stop-Service -Name $_.Name -Force
}

下载地址:VMWareService.zip

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 设置的自定义属性。

PowerShell 技能连载 - 锁定屏幕

借助 WPF,PowerShell 用几行代码就可以创建窗口。以下是一个有趣的关于透明屏幕覆盖层的例子。

您可以调用 Lock-Screen 并且传入一个脚本块和一个标题。PowerShell 将会用它的覆盖层锁定屏幕,再次执行代码将解锁。

function Lock-Screen([ScriptBlock] $Payload={Start-Sleep -Seconds 5}, $Title='Busy, go away.')
{
    try
    {
      $window = New-Object Windows.Window
      $label = New-Object Windows.Controls.Label

      $label.Content = $Title
      $label.FontSize = 60
      $label.FontFamily = 'Consolas'
      $label.Background = 'Transparent'
      $label.Foreground = 'Red'
      $label.HorizontalAlignment = 'Center'
      $label.VerticalAlignment = 'Center'

      $Window.AllowsTransparency = $True
      $Window.Opacity = .7
      $window.WindowStyle = 'None'
      $window.Content = $label
      $window.Left = $window.Top = 0
      $window.WindowState = 'Maximized'
      $window.Topmost = $true

      $null = $window.Show()
      Invoke-Command -ScriptBlock $Payload
    }
    finally { $window.Close() }
}

$job =
{
  Get-ChildItem c:\windows -Recurse -ErrorAction SilentlyContinue
}

Lock-Screen -Payload $job -Title 'I am busy, go away and grab a coffee...'

您很快就会发现,锁屏确实可以防止鼠标点击,但是并不会屏蔽按键。这是一个有趣的技术,不是绝对安全的锁定。

PowerShell 技能连载 - 创建临时密码

以下是一些为您创建不同长度随机密码的代码:

$length = 8
$characters = [Char[]]((31..50) + (65..90) + (97..122))
$characters = $characters -ne 'O' -ne 'o' -ne 'l' -ne '1' -ne '-'
$password = -join ($characters | Get-Random -Count $length)
"Your temporary $length-character-password is $password"

您的密码长度通过 $length 变量设置。用于构成密码的字符集存放在 $characters 变量中。缺省情况下使用 ASCII 编码为 31-50、65-90、97-122 的所有字符。如您所见,通过 -ne 操作符,您可以调整列表和排除字符。在我们的例子中,我们排除了容易拼写错的字母。