PowerShell 在日常开发运维中的应用

Windows PowerShell(以下简称 PowerShell)是微软专门为 Windows 系统管理员设计的命令行壳(Shell)程序。PowerShell 不再像一般的命令行程序接受脚本并返回结果,基于 .NET Framework 的设计让管理员可以在脚本中使用对象并以编程的方式来改变环境。

本场Chat首先会带领大家零基础入门 PowerShell,然后针对日常开发、运维场景介绍 PowerShell 命令,提供可操作的命令及参数组合,方便日常使用。最后将通过一些简单示例演示通过 PowerShell 一键部署环境等。

本场 Chat 您将学到如下内容:

  1. PowerShell 环境;
  2. PowerShell 文件操作;
  3. PowerShell 网络操作;
  4. PowerShell 程序安装;
  5. PowerShell 操作注册表;
  6. PowerShell 控制权限;
  7. PowerShell 配置 IIS;
  8. PowerShell 注册 Windows 定时任务;
  9. PowerShell 注册 Windows 服务;
  10. PowerShell 的无限可能性;
  11. 演示:PowerShell 一键部署开源 CMS 环境。

概述

近年来IT行业发展迅速,竞争激烈,软件项目周期越来越短,而项目的规模和复杂度却直线上升。无论是开发运维都充满挑战,软件团队开始采用敏捷、DevOps 等手段提高生产效率,个人方面也开始实施量化和时间管理,期待整体水平的提高。

DevOps 时代,运维与开发一样开始讲求统一、一致、持续、同构等特性,也同样需要被量化和管理。如同软件编程的领域语言,软件设计出现了 UML,我们也期待有工具能在一致性层面解决运维问题。

为什么是 PowerShell?

PowerShell 是微软命令行外壳(Shell)程序和脚本编程环境,因结合了 .NET CLI(公共语言接口)的设计,就拥有了类编程语言的部分能力,如面向对象概念中的类、方法和变量作用域,可以采用面向对象方式来编写脚本。另外PowerShell吸收了近年来流行的模块化设计和包管理的理念,提供编程模型可供第三方软件提供商开发可导入模块,如 MS SQL Server、Office、Azure、Amazon 等都根据自己的软件产品特点,开发了基于 PowerShell 支持的模块,方便了日常开发运维,为自动化提供了丰富的工具。

PowerShell 简介

PowerShell 命令称为 Cmdlet(Command-let),大致为以下结构:

命令 -参数1 参数值1 -参数2 参数值2 ...|管道命令1 ...|管道命令2 ...|...

其组件主要包括:

  • 命令(Cmdlet)

PowerShell 的命令一般是动名词,如 Remove-Item, Start-Process 等,功能从字面显而易见。

  • 参数(Parameter)

参数包含两部分:参数名和参数值,参数名代表参数的功能,同时约束了参数值的类型。PowerShell 的参数值类型非常丰富,可以但不限于以下类型:

  • 文本——简单的字符串类型,如路径、名称、ID等

  • 数组——基本类型的数组

  • 列表——这里指无指定类型要求的参数列表,出现的比较少

  • 管道(Pipe)

| 符号在命令行中代表管道,管道的意思是 | 前面的命令行表达式返回值作为 | 后命令行表达式的输入参数。

PowerShell 运行环境

在 Windows 环境下,可直接在命令行下输入 PowerShell 进入命令行(脚本运行)环境,提示符左边会出现 PS 字样。Mac 环境下可通过安装 PowerShell app 然后点击图标进入。

与 Windows 命令行的命令执行和批处理方式类似,PowerShell 即支持直接运行命令,也执行通过脚本(.ps1)文件编写并于命令行中调用。除此以外部分第三方软件中也支持采用 PowerShell 实现部署及运维操作,我们称之为代码块(Script Block)方式,以下是各种模式的使用场景:

  • 直接执行的 PowerShell 控制台命令 - 人工部署、人工运维
  • 命令行脚本(.ps1 文件)
  • 无参数/有参数 - 自动化部署、自动化运维
  • 控制台交互 - 半自动化运维
  • 第三方软件中配置的代码块(如Octopus) - 自动化部署

启程:确认环境&获得帮助

现在我们开始学习 PowerShell,本教程特别适合零基础学员,所有的语句都可随手尝试。不过我要打破一下常规,第一个命令不是输出 Hello,World!,我们先要了解我们的 PowerShell。

PS > $PSVersionTable

请注意 > 右边才是命令。这是 PowerShell 环境下使用最频繁的系统变量 $PSVersionTable,它会输出你当前 PowerShell 的版本和环境信息,如果你的 PowerShell 版本低于 4,请从微软下载中心更新 PowerShell 软件包。

然后我们来学习如何获得帮助,可能有人会问“搜索”不就行了,不然,想要系统地学习 Cmdlet 获得更多的潜力你需要深入了解每一个你用过的 Cmdlet,我这里会带大家入门,要继续深入学习需要“官方手段”,那就是 PowerShell 标准获得帮助的方法。

Get-Help:这个命令会给你讲述如何获得帮助,最基本的获得帮助方法如下:

  • Get-Process -?:对指定 Cmdlet 问询帮助,直接加 -?参数,想查询在线帮助?简单,请输入 Get-Help Get-Process -Online 此命令帮助你查询 Get-Process 的在线帮助,网页会直接在浏览器中打开。
  • Get-Help About_Modules:查看关于模块方面的帮助
  • Get-Help remoting:查看具有 remoting 关键字的内容

对于“实用党”肯定是希望快速找到能“剪切+粘贴”的示例,请用 Get-Help Get-Process -examples 获得示例及相关说明。

最重要的是,如果你感觉你的帮助不是很新,或在开始你的 PowerShell 旅行之前更新一下你的知识库(帮助),请输入 Update-Help -Force,这个命令会连线更新你所有已安装模块的帮助内容。下面我们就进入动手环境,大家来体验一下玩转 PowerShell 的快乐吧!

文件操作

文件创建

命令:Add-Item C:\FOLDER\TEST.txt

作用: 创建文件,当文件不存在时会创建空文件(0字节文件)。

当文件存在的时候会出现警告信息如下:

new-item : The file 'C:\FOLDER\TEST.txt' already exists.

这时我们一般会有两种选择,第一是强制覆盖,第二则是忽略(不动原来文件)。

强制执行

强制执行,一般代表着当前行为会执行,结果会改变原状态。对于 New-Item 来说就是用 0 字节文件覆盖原来已经存在的文件,增加强制参数 -Force,很多命令都会有强制执行参数需要时可灵活选择,如下:

Add-Item C:\FOLDER\TEST.txt -Force 

作用:即如果存在文件并且有内容,这句命令过后也会被重置为 0 字节的空文件。

忽略错误

如果不想覆盖已经生成的文件,即忽略错误发生继续向下执行或结束,这时我们需要用到参数 ErrorAction 来定义错误发生时的动作即我们想如何处理错误,大多数情况下我们会采用忽略错误继续执行或结束,很多命令你也都会有此参数可灵活实用,如下:

Add-Item C:\FOLDER\TEST.txt -ErrorAction  SilentlyContinue

作用:-ErrorAction SilentlyContinue 参数及参数值代表忽略错误继续执行。

删除文件

命令:Remove-Item C:\FOLDER\TEST.txt

作用:删除置顶目录的文件。

创建/删除目录

我们尝试了文件的创建和删除,小伙伴们可能会问,那目录呢?很简单,在上面的两个命令加上 Type 参数并且指定为 Directory 即可进行目录操作:

    Add-Item C:\FOLDER -Type Directory     Remove-Item C:\FOLDER -Type Directory

作用:添加/删除指定的目录。

文件拷贝/替换

上面我们通过命令介绍和动手的方式已经对 PowerShell 命令的执行有了部分了解,下面我们结合项目开发中的例子了解一下 PowerShell 脚本的编写。

假设我们有三个开发环境:开发环境(DEV)、集成测试环境(STG)、生产环境(PROD)。域名分别为 myapp.dev.company.com、myapp.stg.company.com、myapp.company.com(生产环境直接使用最终域名)。

我们采用 ASP.NET 进行开发,其默认配置文件为 web.config,为了不同的环境我们有不同的文件进行对应,如:web.dev.config、web.stg.config 和 web.prod.config,而不同环境中应用的文件夹名字与域名保持一致。

需求是,我们要在部署后使用不同环境的配置文件,即文件替换。

这时我们需要编写脚本,Windows 下的各位有福了,因为 Windows 环境有个 PowerShell 自带的 IDE 环境叫 PowerShell ISE,搜索并打开它就可以进行脚本编辑,它本身包括智能提示和一个位于右下方的 PowerShell 命令运行环境,完成脚本编辑可随时通过点击“运行”按钮执行。(脚本编写和脚本参数问题参加下面的“脚本编写”章节)Mac 同志们也不要太悲哀,找个文本编辑器复制下面脚本并在 PowerShell 命令行环境通过 PS scriptfilename.ps1的方式运行脚本即可。

然后就让我们在 IDE 环境中尝试以下脚本:

    $folder="myapp.dev.company.com"     $environment="dev"     $source="D:\"+$folder+"\web."+$environment+".config"     $destination="D:\"+$folder+"\web.config"     Copy-Item $source -Destination $destination 

这里我们使用了变量 \$folder\$destination,做了字符串拼接,然后返回给字符串变量 \$source\$destination,最后将两个变量作为参数值传递给 Cmdlet 完成脚本。

你可能会问这样不就在脚本中固定了环境?我们可以给我们的脚本传值或者在部署工具如 Octopus 中设置环境变量(也就 是\$folder\$environment 的值),这样就解决了不同环境使用不同的目录和文件的问题。

检查文件/目录是否存在

我们可以使用 Test-Path 命令“测试”目录或文件是否存在。

    $if_file_existed = Test-Path "C:\FOLDER\TEST.txt" 

然后通过 IF 进行判断,在“存在”和“不存在”两个程序块中填入我们需要执行的代码:

     if(!$file_exist)    {    #不存在的情况    ...    }    else    {    #存在的情况    ...    }

脚本编写

Windows PowerShell ISE 是 PowerShell 脚本编写的集成开发环境,是上下拆分的窗口结构,上面是脚本编辑区,下面是命令行区,方便实时对脚本运行调试。使用 ISE 的好处还有一个就是它带有智能提示,参数智能列表(包括参数名和参数值枚举)不说,如果参数是文件或目录,还会在参数值输入时自动提示文件夹或文件名,十分方便。

在命令行输入脚本名称要注意使用脚本全路径,所以在部署时首先要保证脚本在当前执行路径或固定路径才好调用。

     For($i=0;$i -lt $args.Count; $i++)     {    ​    Write-Host "parameter $i : $($args[$i])"     }

这里的 Write-Host 是输出到控制台,如果向脚本传递了参数,所有的参数会以空格拆分赋值给 \$args 数组,此段代码的作用就是向控制台输出所有的参数。举例我们需要向脚本输入两个参数:

    C:\script.ps1 "C:\FOLDER1\TEST.txt" "C:\FOLDER2\TEST.txt" 

则如果需要取得"C:\FOLDER1\TEST.txt"和"C:\FOLDER2\TEST.txt",应该使用的变量就是 \$args[0]\$args[1]

注册表操作

注册表操作一般用于复杂配置来改变已安装的软件环境,如 Office 配置、Windows 配置等,适合有一定注册表操作经验的开发人员使用,因本专题不是专门的注册表专题,这里直接列出示例代码供参考使用。

首先是删除已存在注册表项(保证不与我们要创建的注册表项冲突)

    Remove-Item "HKLM:\SOFTWARE\Classes\AppID\{048EB43E-2059-422F-95E0-557DA96038AF}" -ErrorAction SilentlyContinue

然后是创建注册表项(Out-Null 代表空输出):

    $root = "HKLM:\SOFTWARE\Classes\AppID"     $appid="{048EB43E-2059-422F-95E0-557DA96038AF}"     New-Item -Path $root -Name $appid -Force | Out-Null 

最后是给注册表项创建键和值(Key/Value):

    $registryPath = "HKLM:\SOFTWARE\Classes\AppID\{048EB43E-2059-422F-95E0-557DA96038AF}"     New-ItemProperty -Path $registryPath -Name "(default)" -Value "Microsoft PowerPoint Slide" -PropertyType STRING -Force | Out-Null     New-ItemProperty -Path $registryPath -Name "AuthenticationLevel" -Value "1" -PropertyType DWORD -Force | Out-Null

这里要注意注册表项的 PropertyType 参数类型代表着键的数据类型。

验证注册表项:

    Get-Item "HKLM:\SOFTWARE\Classes\AppID\{048EB43E-2059-422F-95E0-557DA96038AF}" 

示例 2:

    $registryPath = "HKLM:\System\CurrentControlSet\Control\Lsa"     New-ItemProperty -Path $registryPath -Name "DisableDomainCreds" -Value "0" -PropertyType DWORD -Force | Out-Null 

配置 IIS 服务器

Windows 环境进行 Web 开发就会用到 IIS 服务器,这时我们可能会需要 PowerShell 来为我们自动配置 IIS 站点应用的权限,这里面部分参数值涉及到 IIS Metadata 需要 IIS 相关开发经验或者到微软的网站及进行查询。

Web 应用程序池配置

首先,引入 ServerManager,注意此包只在服务器版本 Windows 中才有:

    Import-Module ServerManager 

然后是添加 Feature,类似安装组件:

    Add-WindowsFeature Web-Scripting-Tools

导入 Web 管理包:

    Import-Module WebAdministration 

然后的操作是获取 WebApp1 应用程序池的配置项,将其 IdentifyType 修改为 LocalSystem(0)。

    $demoPool = Get-Item IIS:\AppPools\webapp1    $demoPool.processModel.identityType = 0     $demoPool | Set-Item 

修改目录权限

Windows 下 Web 开发经常需要对 Web App 目录配置 IUSR 权限以让 App 有权限进行文件访问:

$permission="IUSR",,"FullControl,Read,Modify","ContainerInherit,ObjectInherit","None","Allow"     $rule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission     $folders = Get-Childitem "D:\apps" -Recurse | Where-Object {$_.PSISContainer}     Foreach ($folder in $folders) {     $path = $folder.FullName     $acl = Get-Acl $path     $acl.SetAccessRule($rule)     Set-Acl $path $acl -ErrorAction SilentlyContinue     }

以上代码实现为用户指定要配置的权限 \$permission,创建访问规则对象 \$rule,然后遍历文件夹将权限赋予到每个文件夹中。

重新启动 IIS

命令:

invoke-command -scriptblock {iisreset /restart}`

作用:重启 IIS 以加载更新配置

软件安装

此部分笔者整理了软件安装过程中经常会使用到的脚本:如普通软件安装、MSI 程序包安装、Windows 特性安装、程序包下载、解压缩等。

普通软件安装

命令:

Start-Process -FilePath "D:\apps\software\vc14_vc_redist.x64.exe" -ArgumentList "/q /norestart" -Wait

作用:通过安装文件支持的静默安装(quiet installation,一般参数为 /q)或后台安装(background installation)参数等实现软件自动后台安装。

MSI 程序包安装

MSI 程序包安装脚本如下:

    $install_folder="c:\lab\mysql"    $arguments = @(     ​    "/i"     ​    "c:\lab\mysql.msi"     ​    "/qn"     ​    "/norestart"     )    $arguments+="INSTALLDIR=\`"$install_folder\`""    #install with msi    Start-Process -FilePath msiexec -ArgumentList $arguments -Wait 

作用:

MSI 程序包可通过 msiexec 程序进行安装,msi 安装包普遍使用一致的安装参数,所以自动化起来更方便。

Windows 特性安装

在很多时候我们需要加载需要的 Windows 特性以支持开发和软件运行,如下例子我们添加所有 ASP.NET Web 应用可能使用到的 Windows 特性:

    Install-WindowsFeature -Name Web-Default-Doc, Web-Dir-Browsing, Web-Http-Errors, Web-Static-Content, Web-Http-Redirect, Web-Http-Logging,Web-Stat-Compression, Web-Dyn-Compression, Web-Filtering, Web-Basic-Auth, Web-Net-Ext, Web-Net-Ext45, Web-Asp-Net, Web-Asp-Net45,Web-CGI, Web-ISAPI-Ext, Web-ISAPI-Filter, Web-Mgmt-Console 

网络文件下载

命令:

Invoke-WebRequest -Uri $download_url -OutFile $destination_folder\$download_filename

作用:

下载 \$download_url 地址中的文件到 \$destination_folder 文件夹下并重命名为 \$download_filename 文件名。也可用于网页、Javascript、CSS 等网页静态资源的保存。

P.S: 对于 github 文件下载可能需要修改 Http 安全协议,在执行下在前执行下面脚本:

    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 

解压缩

命令:

    Add-Type -AssemblyName "[system.io.compression.filesystem](http://system.io.compression.filesystem/)"     [[io.compression.zipfile](http://io.compression.zipfile/)]::ExtractToDirectory("C:\a.zip","C:\A") 

作用:将 C 盘下面 a.zip 文件解压缩到 C:\A 目录。

启动服务

命令:Start-Service -Name "MariaDB"

作用:一般用于软件安装后自动启动 Windows 服务。

调试与日志

命令:

Write-output "Adding votes to the replicas was successfull" >> $log_file

作用:为了调试脚本我们需要输出一些有助于分析的信息,可以采用 Write-Output 将内容推送到 $log_file,每次一行形成日志文件。

不是终结,只是开始

笔者先要对各位看过说声抱歉,本来是要把所有实际项目中遇到的问题及通过 PowerShell 解决的办法分享出来,但部分解决方案在项目后有了更新的知识,还有一大部分涉及的 PowerShell 功能复杂并不是和新手理解也没办法在短小篇幅中解释清楚,后面我会做一个系列单独对每块有价值的部分详细阐述。对于动手实践,希望各位看官能根据你们开发和运维环境的需求,运用上面的命令实现自己项目中的开发和运维自动化,并来与我讨论,我会竭尽所能地帮助你们解决实际问题,欢迎关注微信公众号“敏捷架构”(minjiejiagou)一起交流学习。


本文首发于GitChat,未经授权不得转载,转载需与GitChat联系。

阅读全文: http://gitbook.cn/gitchat/activity/5b2714cc3130202ab558c687

您还可以下载 CSDN 旗下精品原创内容社区 GitChat App ,阅读更多 GitChat 专享技术内容哦。

FtooAtPSkEJwnW-9xkCLqSTRpBKX

你可能感兴趣的:(PowerShell 在日常开发运维中的应用)