PowerShell 技能连载 - 存取 SQLServer 数据库

适用于 PowerShell 所有版本及 SQLServer

您在使用 SQL Server 吗?以下是一段可以进行 SQL 查询并获取数据的 PowerShell 脚本模板。只需要确保填写了正确的用户信息、服务器地址和 SQL 语句即可:

$Database                       = 'Name_Of_SQLDatabase'
$Server                         = '192.168.100.200'
$UserName                         = 'DatabaseUserName'
$Password                       = 'SecretPassword'

$SqlQuery                       = 'Select * FROM TestTable'

# Accessing Data Base
$SqlConnection                  = New-Object -TypeName System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Data Source=$Server;Initial Catalog=$Database;user id=$UserName;pwd=$Password"
$SqlCmd                         = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.CommandText             = $SqlQuery
$SqlCmd.Connection              = $SqlConnection
$SqlAdapter                     = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand       = $SqlCmd
$set                            = New-Object data.dataset

# Filling Dataset
$SqlAdapter.Fill($set)

# Consuming Data
$Path = "$env:temp\report.hta"
$set.Tables[0] | ConvertTo-Html | Out-File -FilePath $Path

Invoke-Item -Path $Path

PowerShell 技能连载 - 创建彩色的 HTML 报告

适用于 PowerShell 所有版本

要将结果转换为彩色的自定义报告,只需要定义三个脚本块:一个生成 HTML 文档的头部,另一个生成尾部,还有一个对报表中的列表做循环,针对每一个列表项做处理。

然后,将这些脚本块传递给 ForEach-Object。它接受一个 begin、一个 process 和一个 end 脚本块。

以下是一个示例代码,演示了如何创建一个彩色的服务状态报表:

$path = "$env:temp\report.hta"

$beginning = {
 @'
    <html>
    <head>
    <title>Report</title>
    <STYLE type="text/css">
        h1 {font-family:SegoeUI, sans-serif; font-size:20}
        th {font-family:SegoeUI, sans-serif; font-size:15}
        td {font-family:Consolas, sans-serif; font-size:12}

    </STYLE>

    </head>
    <image src="http://www.yourcompany.com/yourlogo.gif" />
    <h1>System Report</h1>
    <table>
    <tr><th>Status</th><th>Name</th></tr>
'@
}

$process = {
    $status = $_.Status
    $name = $_.DisplayName

    if ($status -eq 'Running')
    {
        '<tr>'
        '<td bgcolor="#00FF00">{0}</td>' -f $status
        '<td bgcolor="#00FF00">{0}</td>' -f $name
        '</tr>'
    }
    else
    {
        '<tr>'
        '<td bgcolor="#FF0000">{0}</td>' -f $status
        '<td bgcolor="#FF0000">{0}</td>' -f $name
        '</tr>'
    }
}


$end = {
@'
    </table>
    </html>
    </body>
'@


}


Get-Service |
  ForEach-Object -Begin $beginning -Process $process -End $end |
  Out-File -FilePath $path -Encoding utf8

Invoke-Item -Path $path

PowerShell 技能连载 - 关闭“完整语言”模式

适用于 PowerShell 所有版本

PowerShell 可以有多种方法作出限制。一种是将语言模式从 FullLanguage 改为 RestrictedLanguage。这是一种无法撤销的方法,最坏可以关闭并重开 PowerShell:

$host.Runspace.SessionStateProxy.LanguageMode = 'RestrictedLanguage'

一旦设置成 RestrictedLanguage,PowerShell 将只能执行指令。它将再也无法执行对象的方法或存取对象的属性,并且您也无法定义新的函数。

所以 RestrictedLanguage 基本上是一个安全的锁,锁定以后 PowerShell 只能执行指令但无法深入到底层的 .NET 或用新创建的函数覆盖现有的命令。

PowerShell 技能连载 - 控制可执行文件的执行

适用于 PowerShell 所有版本

PowerShell 将所有可执行程序(扩展名为 EXE 的文件)视为普通的命令。您甚至可以限制 PowerShell 不能执行任何可执行程序或只能执行白名单内的程序。

缺省的设置是允许任何 EXE 执行:

PS> $ExecutionContext.SessionState.Applications
*

该设置为仅允许 ping.exeregedit.exe 执行:

$ExecutionContext.SessionState.Applications.Clear()
$ExecutionContext.SessionState.Applications.Add('ping.exe')
$ExecutionContext.SessionState.Applications.Add('regedit.exe')

以下是结果:

PS> $ExecutionContext.SessionState.Applications
ping.exe
regedit.exe

显然地,您可以轻松地将设置恢复到缺省状态:

PS> $ExecutionContext.SessionState.Applications.Add('*')

PS> explorer

PS>

所以,该设置可以使执行 EXE 程序变得更困难(或者说防止不小心运行了不该运行的 EXE)。若真要将它作为安全策略,您还需要关闭所谓的“语言模式”。

当语言模式关闭时,您无法直接存取 .NET 对象。这意味着您无法在当前的 PowerShell 会话中回退该操作。我们将在明天详细介绍语言模式设置。

PowerShell 技能连载 - 伪造对象类型

适用于 PowerShell 3.0 及以上版本

PowerShell 内部的类型扩展系统的作用是负责将对象转换为文本。它的实现方法是通过查询一个名为“PSTypeName”的属性。您可以为自定义的对象添加这个属性来模拟其它对象类型并使 ETS 用相同方式显示该对象:

$object = [PSCustomObject]@{
  ProcessName = 'notepad'
  ID = -1
  PSTypeName = 'System.Diagnostics.Process'
}

The object pretends to be a process object, and ETS will format it accordingly:

PS> $object

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
              0        0          0     0              -1 notepad



PS>

PowerShell 技能连载 - 创建新对象

适用于 PowerShell 3.0 或以上版本

这是一个创建自定义对象的简单有效的方法:

$object = [PSCustomObject]@{
  Name = 'Weltner'
  ID = 123
  Active = $true
}

这将创建一个包含预设属性值的完整功能的 PowerShell 对象:

PS> $object

Name                                                ID                    Active
----                                                --                    ------
Weltner                                            123                     True



PS> $object.Name
Weltner

PS> $object.Active
True

PS>

PowerShell 技能连载 - 在非域环境中使用 PowerShell 远程操作

适用于 PowerShell 3.0 及以上版本

缺省情况下,当您通过 Enable-PSRemoting 来启用 PowerShell 远程操作时,只启用了 Kerberos 身份验证。这要求双方主机处于同一个域(或信任的域)中,并且仅能通过计算机名访问(很可能包括域名前缀)。它无法跨域、通过域之外的机器,或通过 IP 地址来访问。

要达到上述目的,您需要在启用远程操作的机器上做一些调整。在初始化连接的机器上以管理员权限运行 PowerShell 控制台,键入以下代码:

PS> Set-Item WSMan:\localhost\Client\TrustedHosts -Value * -Force

如果该路径不可用,您可能需要在该机器上(临时地)启用 PowerShell 远程操作(用 Enable-PSRemoting –SkipNetworkProfileCheck –Force)。

当您做了上述改动以后,就可以支持 NTLM 验证了。只需要记住从现在开始,要访问加入域的计算机,您需要通过 -Credential 参数提交用户名和密码。

PowerShell 技能连载 - 启用、禁用 PowerShell 远程操作

适用于 PowerShell 3.0 及更高版本

如果您想通过 PowerShell 访问一台远程计算机,那么在目标机器(您想访问的机器)上,以管理员身份运行这行代码:

PS> Enable-PSRemoting -SkipNetworkProfileCheck -Force

执行完之后,您就可以通过别的计算机访问该计算机了——假设您拥有目标机器的管理员权限,您需要指定计算机名而不是它的 IP 地址,并且两台机器都需要在同一个域中。

要交互式地连接目标机器,使用这行代码:

PS> Enter-PSSession -ComputerName targetComputerName

要在远程计算机上运行代码,请使用这种方式:

PS> Invoke-Command -ScriptBlock { Get-Service } -ComputerName targetComputerName

PowerShell 技能连载 - 从文件中读取系统日志

适用于 PowerShell 所有版本

有些时候,您可能会需要读取已经导出到磁盘上的系统日志文件,或者您希望直接从一个“evtx”格式的文件中读取系统日志。

以下是实现的方法:

$path = "$env:windir\System32\Winevt\Logs\Setup.evtx"
Get-WinEvent -Path $path

PowerShell 技能连载 - WMI 搜索工具

适用于 PowerShell 所有版本

WMI 是一个很棒很强大的技术:只需要指定一个 WMI 类名,您就可以获取该类的所有实体。

PS> Get-WmiObject -Class Win32_BIOS


SMBIOSBIOSVersion : 76CN27WW
Manufacturer      : LENOVO
Name              : 76CN27WW
SerialNumber      : 1006250300406
Version           : LENOVO - 1

那么如何知道有哪些 WMI 类呢?以下是一个搜索工具函数:

function Find-WMIClass
{
   param
   (
      [Parameter(Mandatory=$true)]
      $SearchTerm = 'Resolution'
   )

   Get-WmiObject -Class * -List |
   Where-Object { $_.Properties.Count -ge 3 } |
   Where-Object { $_.Name -notlike 'Win32_Perf*'  } |
   Where-Object {
      $ListOfNames = $_.Properties | Select-Object -ExpandProperty Name
      ($ListOfNames -like "*$SearchTerm*") -ne $null
   } |
   Sort-Object -Property Name
}

只需要指定一个搜索条件。该函数将会查找所有属性名中包含搜索条件的 WMI 类(可以用通配符来扩大搜索范围)。

这段代码能搜索属性以“resolution”结尾的 WMI 类:

PS> Find-WMIClass -SearchTerm *resolution


   NameSpace: ROOT\cimv2

Name                                Methods              Properties
----                                -------              ----------
CIM_CacheMemory                     {SetPowerState, R... {Access, AdditionalErr...
CIM_CurrentSensor                   {SetPowerState, R... {Accuracy, Availabilit...
CIM_FlatPanel                       {SetPowerState, R... {Availability, Caption...
CIM_Memory                          {SetPowerState, R... {Access, AdditionalErr...
CIM_MonitorResolution               {}                   {Caption, Description,...
CIM_NonVolatileStorage              {SetPowerState, R... {Access, AdditionalErr...
CIM_NumericSensor                   {SetPowerState, R... {Accuracy, Availabilit...
CIM_PCVideoController               {SetPowerState, R... {AcceleratorCapabiliti...
CIM_PointingDevice                  {SetPowerState, R... {Availability, Caption...
CIM_Printer                         {SetPowerState, R... {Availability, Availab...
CIM_Tachometer                      {SetPowerState, R... {Accuracy, Availabilit...
CIM_TemperatureSensor               {SetPowerState, R... {Accuracy, Availabilit...
CIM_VideoController                 {SetPowerState, R... {AcceleratorCapabiliti...
CIM_VideoControllerResolution       {}                   {Caption, Description,...
CIM_VolatileStorage                 {SetPowerState, R... {Access, AdditionalErr...
CIM_VoltageSensor                   {SetPowerState, R... {Accuracy, Availabilit...
Win32_CacheMemory                   {SetPowerState, R... {Access, AdditionalErr...
Win32_CurrentProbe                  {SetPowerState, R... {Accuracy, Availabilit...
Win32_DisplayControllerConfigura... {}                   {BitsPerPixel, Caption...
Win32_MemoryArray                   {SetPowerState, R... {Access, AdditionalErr...
Win32_MemoryDevice                  {SetPowerState, R... {Access, AdditionalErr...
Win32_NetworkAdapterConfiguration   {EnableDHCP, Rene... {ArpAlwaysSourceRoute,...
Win32_PointingDevice                {SetPowerState, R... {Availability, Caption...
Win32_Printer                       {SetPowerState, R... {Attributes, Availabil...
Win32_PrinterConfiguration          {}                   {BitsPerPel, Caption, ...
Win32_SMBIOSMemory                  {SetPowerState, R... {Access, AdditionalErr...
Win32_TemperatureProbe              {SetPowerState, R... {Accuracy, Availabilit...
Win32_VideoConfiguration            {}                   {ActualColorResolution...
Win32_VideoController               {SetPowerState, R... {AcceleratorCapabiliti...
Win32_VoltageProbe                  {SetPowerState, R... {Accuracy, Availabilit...

下一步,选择一个类名并观察它的实际数据:

PS> Get-WmiObject -Class CIM_CacheMemory | Select-Object -Property *