多数 Windows 许可证激活任务可以通过一个古老的名为 slmgr.vbs 的 VBScript 来实现自动化。不过,用这个工具来获取信息的意义不大。因为 slmgr.vbs 使用的事本地化的字符串,并且将所有数据转换为一个大字符串格式。
一个更好的方法是跳过 slmgr.vbs,而直接查询信息源。要搞清 slmgr.vbs 如何实现这些功能,您可以查看该脚本的源码。请在 PowerShell ISE 中运行这段代码:
1 2 3 4
# get the path to the script file $Path = Get-Command slmgr.vbs | Select-Object-ExpandProperty Source # load the script file $file = $psise.CurrentPowerShellTab.Files.Add($Path)
This command is actually an ancient VBScript. To read all of your license settings, for example, try this: 这个命令实际上是一个古老的 VBScript。例如要读取所有许可证设置,请使用以下代码:
# characters from dark to light $characters = '$#H&@*+;:-,. '.ToCharArray() $c = $characters.count
# load image and get image size $image = [Drawing.Image]::FromFile($path) [int]$maxheight = $image.Height / ($image.Width / $maxwidth)/ $ratio
# paint image on a bitmap with the desired size $bitmap = new-object Drawing.Bitmap($image,$maxwidth,$maxheight)
# use a string builder to store the characters [System.Text.StringBuilder]$sb = ""
# take each pixel line... for ([int]$y=0; $y-lt$bitmap.Height; $y++){ # take each pixel column... for ([int]$x=0; $x-lt$bitmap.Width; $x++){ # examine pixel $color = $bitmap.GetPixel($x,$y) $brightness = $color.GetBrightness() # choose the character that best matches the # pixel brightness [int]$offset = [Math]::Floor($brightness*$c) $ch = $characters[$offset] if (-not$ch){ $ch = $characters[-1] } # add character to line $null = $sb.Append($ch) } # add a new line $null = $sb.AppendLine() }
# clean up and return string $image.Dispose() $sb.ToString() }
# wait 5 seconds for spooler service to stop $serviceToMonitor = Get-Service-Name Spooler $desiredStatus = [System.ServiceProcess.ServiceControllerStatus]::Stopped $maxTimeout = New-TimeSpan-Seconds5
try { $serviceToMonitor.WaitForStatus($desiredStatus, $maxTimeout) } catch [System.ServiceProcess.TimeoutException] { Write-Warning'Service did not reach desired status within timeframe.' }
# take a simple XAML template with some text $xaml = @" <TextBlock xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">$Text</TextBlock> "@
Add-Type-AssemblyName PresentationFramework
# turn it into a UIElement $reader = [XML.XMLReader]::Create([IO.StringReader]$XAML) $result = [Windows.Markup.XAMLReader]::Load($reader)
# render it in memory to the desired size $result.Measure([System.Windows.Size]::new([Double]::PositiveInfinity, [Double]::PositiveInfinity)) $result.Arrange([System.Windows.Rect]::new($result.DesiredSize)) $result.UpdateLayout()
# write it to a bitmap and save it as PNG $render = [System.Windows.Media.Imaging.RenderTargetBitmap]::new($result.ActualWidth, $result.ActualHeight, 96, 96, [System.Windows.Media.PixelFormats]::Default) $render.Render($result) Start-Sleep-Seconds1 $encoder = [System.Windows.Media.Imaging.PngBitmapEncoder]::new() $encoder.Frames.Add([System.Windows.Media.Imaging.BitmapFrame]::Create($render)) $filestream = [System.IO.FileStream]::new($filename, [System.IO.FileMode]::Create) $encoder.Save($filestream)
# clean up $reader.Close() $reader.Dispose()
$filestream.Close() $filestream.Dispose()
# return the file name for the generated image $filename }
以下是使用方法:
1 2 3
PS> $file = Convert-TextToImage-Text'Red Alert!'-Font Stencil -FontSize60-Foreground Red -Background Gray