利用Powershell来批量迁移IIS应用

appcmd 不好用,导出的xml文件还要手动进行调整才可以运行。

Powershell有方便的远程执行功能,可以利用来进行批量创建IIS应用。

远程执行Get-IISSite.ps1 ,导出csv,然后创建app pool和application

Get-IISServerManager
New-IISSite

 在PowerShell运行*.ps时,出现*.ps1 is not digitally signed. The script will not execute on the systeGet-ExecutionPolicy -List解决方法:

在PowerShell中执行
用Set-ExectionPolicy 设置执行策略
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass

 

Get-IISSite.ps1 这个脚本来自下面的工具包,不过原先版本不能导出80端口的全部应用,我修改了下原先的脚本,加了些属性。

 
<#
.Synopsis
   Get IIS Site information from a local or remote computer.
.DESCRIPTION
   Get IIS Site information from a local or remote computer.
.NOTES
   Created by: Jason Wasser @wasserja
   Modified: 5/3/2017 02:13:17 PM
.EXAMPLE
   Get-IISSite
.EXAMPLE
   Get-IISSite -ComputerName webserver01
#>
function Get-IISSite
{
    [CmdletBinding()]
    Param
    (
        # ComputerName
        [parameter(ValueFromPipeline=$true,
                    ValueFromPipelineByPropertyName=$true,
                   Position=0)]
        [string[]]$ComputerName = $env:COMPUTERNAME,

        # Credential
        [System.Management.Automation.PSCredential]$Credential=[System.Management.Automation.PSCredential]::Empty
    )

    Begin
    {
        
        # Helper Function to do the work of gathering site detail information.
        function Get-IISSiteInformation {
            #$VerbosePreference = 'Continue'
            try {
                Import-Module -Name WebAdministration -ErrorAction Stop
                # $Websites = Get-ChildItem IIS:Sites
                $Manager=get-iisservermanager
                $Websites=$Manager.sites
                $Pools=$Manager.ApplicationPools
                # $sites[0].Applications[2]

                foreach ($Site in $Websites) {
                    $Bindings = $Site.Bindings
                    $Apps = $Site.Applications
                    
                    foreach ($App in $Apps) {
                        # Creating hash table for object properties
                        $AppPool = $Pools[$App.ApplicationPoolName]

                        $SiteProperties = [ordered]@{
                            Name = $Site.name
                            ID = $Site.ID
                            State = $Site.state
                            # PhysicalPath = $Site.physicalPath
                            # Bindings = $Bindings
                            BindingInformation = $Bindings[0].BindingInformation
                            Port = $Bindings[0].EndPoint.Port
                            AppPool = $AppPool.Name
                            ManagedRunTimeVersion = $AppPool.managedRuntimeVersion
                            AppPoolState = $AppPool.state
                            AppPoolIdentityType = $AppPool.processmodel.identityType
                            AppPoolUsername = $AppPool.processmodel.userName
                            AppPoolPassword = $AppPool.processmodel.Password
                            ComputerName = $env:COMPUTERNAME
                            AppPoolName = $App.ApplicationPoolName
                            AppPath = $App.VirtualDirectories.PhysicalPath
                            EnabledProtocols = $App.EnabledProtocols
                            }

                          $Site = New-Object -TypeName pscustomobject -Property $SiteProperties
                          $Site 
                    }

     
                 }
                }
            catch {
                Write-Error $Error[0].Exception.Message
                }
            }

    }
    Process
    {
        
        # Loop through each supplied computer name.
        foreach ($Computer in $ComputerName) {
            
            # Run function locally if localhost.
            if ($Computer -eq $env:COMPUTERNAME) {
                Write-Verbose 'Getting IIS website information from localhost'
                Get-IISSiteInformation
                }
            # Run function via Invoke-Command on remote computers.
            else {
                Write-Verbose "Getting IIS website information from remote computer $Computer"
                Invoke-Command -ScriptBlock ${function:Get-IISSiteInformation} -ComputerName $Computer -Credential $Credential
                }
            }
    }
    End
    {
    }
}

IISHelper

void Main()
{
    string cmd = "get-iissite | out-string ";
    cmd = @"get-iissite |ForEach-Object {$_.ID,$_.Name,$_.State,$_.ApplicationPool,$_.Applications[0].VirtualDirectories[0].PhysicalPath} | Tee-Object -f d:	emp	est.csv ";
    //cmd = @"get-iissite | % { Write-Output $_.ID , $_.Name, $_.Applications[0].VirtualDirectories[0].PhysicalPath } >   d:	emp	est.csv   ";
    //cmd = @"get-iissite | select   ID,Name,State,PhysicalPath,Bindings | export-csv -path d:	emp	est.csv";
    //Get-Process | Out-File process.txt
    //Get-Process | Tee-Object -f dirs.txt
    //cmd = @"get-childitem iis:sites | select ID,Name,PhysicalPath,ApplicationPool | out-string";
    //cmd = @"Get-ChildItem IIS:Sites ";
    //cmd = @"Get-ChildItem IIS:AppPools | out-string  ";
    // Get-Item -Path "IIS:AppPoolsDefaultAppPool"
    cmd = @" . d:	empget-iissite.ps1 ";
    //var results = RemoteExecute(PCName,UserName,PCPwd,cmd);


    //CreateWebSite(@"myvue2",@"c:inetpubwwwrootmyvue2",8181);
    //RemoveWebSite(@"TestSite2");
    //RemoveAppPool("myvue2");
    //CreateAppPool("myvue2");
    //AppCmdExport("site",@"d:	empsite.xml");
    //ListSites(@"d:	empsite.xml");
    //AppCmdImport("site",@"d:	empsite.xml");

    // ListSites();
    IISWebSite site = ImportSites().ToArray()[6];
    site.Dump();
    CreateWebSite(site);
}

/*
cmd="get-command -module IISAdministration";
cmd="Get-Command -module WebAdministration";

APPCMD.exe set app "sitename/" /applicationPool:"appPoolName"
appcmd add apppool /name:appPoolName /managedRuntimeVersion:"v4.0" /managedPipelineMode:"Integrated"
*/
public string PCName = "server2016";
public string UserName = @"server2016administrator";
public string PCPwd = Util.GetPassword("pwd");
public string ScriptPath = @"d:	empget-iissite.ps1"; // @"\server2016	empget-iissite.ps1"; 
public string AppCmdPath = @"C:windowssystem32inetsrvappcmd.exe";
public string SaveWebSite = @"d:	empwebsite.csv";

public void RestartSite(string site="Default Web Site")
{
    StringBuilder sb = new StringBuilder();
    sb.AppendLine($@"$appCmd = ""{AppCmdPath}"";");
    sb.AppendLine($@"& $appCmd stop site ""{site} Web Site"";");
    sb.AppendLine($@"& $appCmd start site ""{site} Web Site"";");
    string cmd = sb.ToString();
    RemoteExecute(PCName, UserName, PCPwd, cmd);
}

public void AppCmdExport(string type="apppool",string file=@"d:	emp	est.xml"){
    StringBuilder sb = new StringBuilder();
    sb.AppendLine($@"$appCmd = ""{AppCmdPath}"";");
    sb.AppendLine($@"& $appCmd list {type} /config /xml > {file}");
    string cmd = sb.ToString();
    RemoteExecute(PCName, UserName, PCPwd, cmd);
}

public void AppCmdImport(string type="apppool",string file = @"d:	emp	est.xml")
{
    StringBuilder sb = new StringBuilder();
    sb.AppendLine($@"$appCmd = ""{AppCmdPath}"";");
    sb.AppendLine($@"Get-Content {file} | & $appCmd add {type} /in");
    string cmd = sb.ToString();
    RemoteExecute(PCName, UserName, PCPwd, cmd);
}

public void ListSites()
{
    string cmd = $@" . {ScriptPath} ; get-iissite;";
    var results = RemoteExecute(PCName, UserName, PCPwd, cmd);
    var q = from r in results
            select new IISWebSite{
                ID = Convert.ToInt32(r.Properties["ID"].Value)
                ,Name = r.Properties["Name"].Value.ToString()
                ,State = r.Properties["State"].Value.ToString()
                ,BindingInformation = r.Properties["BindingInformation"].Value.ToString()
                ,Port = Convert.ToInt32(r.Properties["Port"].Value)
                ,AppPool = r.Properties["AppPool"].Value.ToString()
                ,ManagedRunTimeVersion = r.Properties["ManagedRunTimeVersion"].Value.ToString()
                ,AppPoolState = r.Properties["AppPoolState"].Value.ToString()
                ,AppPoolIdentityType = r.Properties["AppPoolIdentityType"].Value.ToString()
                ,AppPoolUsername = r.Properties["AppPoolUsername"].Value.ToString()
                ,AppPoolPassword = r.Properties["AppPoolPassword"].Value.ToString()
                ,ComputerName = r.Properties["ComputerName"].Value.ToString()
                ,AppPoolName = r.Properties["AppPoolName"].Value.ToString()
                ,AppPath = r.Properties["AppPath"].Value.ToString()
                ,EnabledProtocols = r.Properties["EnabledProtocols"].Value.ToString()
            };
    q.Dump();
    ExportSites(q.ToList());
}

public void ExportSites(List<IISWebSite> sites)
{
    if (!String.IsNullOrWhiteSpace(SaveWebSite))
    {
        CsvFileDescription outputFileDescription = new CsvFileDescription
        {
            SeparatorChar = ',', 
            FirstLineHasColumnNames = true                                    
        };
        CsvContext cc = new CsvContext();
        cc.Write(sites,SaveWebSite,outputFileDescription);
    }
}

public IEnumerable<IISWebSite>  ImportSites()
{
    CsvFileDescription inputFileDescription = new CsvFileDescription
    {
        SeparatorChar = ',',
        FirstLineHasColumnNames = true
    };
    CsvContext cc = new CsvContext();
    IEnumerable<IISWebSite> results = cc.Read<IISWebSite>(SaveWebSite, inputFileDescription);
    return results;
}

public void ListSites(string file = @"\server2016	empsite.xml")
{
    System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
    doc.Load(file);
    doc.Dump();
    //doc.SelectSingleNode("/appcmd/SITE/site/@name").Dump();
    var sites = doc.SelectNodes("/appcmd/SITE/site");
    sites.Dump();
     var q = from x in sites.Cast<XmlNode>()
              select new
              {
                  id = x.Attributes["id"].Value
                  ,name = x.Attributes["name"].Value
                  ,serverAutoStart = x.Attributes["serverAutoStart"].Value
              };

    q.Dump();
}

public void CreateWebSite(IISWebSite website)
{
    CreateAppPool(website.AppPoolName);
    string cmd = $@"New-IISSite -Name ""{website.Name}"" -BindingInformation ""*:{website.Port}:"" -PhysicalPath ""{ website.AppPath}""
    ;Get-IISSite -Name ""{ website.Name}"" | out-string";
    RemoteExecute(PCName, UserName, PCPwd, cmd);
}

public void CreateWebSite(string appName, string appPath, int port = 80)
{
    string cmd = $@"New-IISSite -Name ""{appName}"" -BindingInformation ""*:{port}:"" -PhysicalPath ""{ appPath}""
    ;Get-IISSite -Name ""{ appName}"" | out-string";
    RemoteExecute(PCName, UserName, PCPwd, cmd);
}

public void RemoveWebSite(string appName)
{
    string cmd = $@"Remove-IISSite -Name ""{appName}"" -Confirm:$false";
    RemoteExecute(PCName, UserName, PCPwd, cmd);
}

public void CreateAppPool(string poolName)
{
    StringBuilder sb = new StringBuilder();
    sb.AppendLine($@"$manager = Get-IISServerManager;");
    sb.AppendLine($@"$pool = $manager.ApplicationPools.Add(""{poolName}"");");
    sb.AppendLine($@"$pool.ManagedPipelineMode = ""Integrated"";");
    sb.AppendLine($@"$pool.ManagedRuntimeVersion = ""v4.0"";");
    sb.AppendLine($@"$pool.Enable32BitAppOnWin64 = $false;");
    sb.AppendLine($@"$pool.AutoStart = $true;");
    sb.AppendLine($@"$pool.StartMode = ""OnDemand"";");
    //sb.AppendLine($@"$pool.ProcessModel.IdentityType = ""ApplicationPoolIdentity"";");
    sb.AppendLine($@"$pool.ProcessModel.IdentityType = ""NetworkService"";");
    sb.AppendLine($@"$Manager.CommitChanges();");
    sb.AppendLine($@"Get-IISAppPool -Name ""{poolName}"" | out-string;");
    string cmd = sb.ToString();
    RemoteExecute(PCName, UserName, PCPwd, cmd);
}

public void RemoveAppPool(string poolName)
{
    StringBuilder sb = new StringBuilder();
    sb.AppendLine($@"$manager = Get-IISServerManager;");
    sb.AppendLine($@"$manager.ApplicationPools[""{poolName}""].Delete();");
    sb.AppendLine($@"$Manager.CommitChanges();");
    sb.AppendLine($@"Get-IISAppPool -Name ""{poolName}"" | out-string;");
    string cmd = sb.ToString();
    RemoteExecute(PCName, UserName, PCPwd, cmd);
}

public List<PSObject> RemoteExecute(string pcname, string uname, string pwd , string cmd)
{

    InitialSessionState initial = InitialSessionState.CreateDefault();
    Runspace runspace = RunspaceFactory.CreateRunspace(initial);
    runspace.Open();
    PowerShell ps = PowerShell.Create();
    ps.Runspace = runspace;
    ps.AddCommand("invoke-command");
    ps.AddParameter("ComputerName", pcname);
    var ss = new System.Security.SecureString();
    foreach (var ch in pwd)
        ss.AppendChar(ch);
    PSCredential cred = new System.Management.Automation.PSCredential(uname, ss);
    ps.AddParameter("Credential", cred);
    ps.AddParameter("ScriptBlock", ScriptBlock.Create(cmd));
    cmd.Dump();
    var results = ps.Invoke();
    results.Dump();
    /*
    foreach (PSObject obj in ps.Invoke())
    {
        obj.Dump();
        obj.Properties["Name"].Value.Dump();
    }
    */
    
    if (ps.Streams.Error.Count > 0)
        Console.WriteLine(ps.Streams.Error[0]);
    return results.ToList();
}

public class IISWebSite
{
    public string Name { get; set; }
    public int ID { get; set; }
    public string State { get; set; }
    public string BindingInformation { get; set; }
    public int Port { get; set; }
    public string AppPool { get; set; }
    public string ManagedRunTimeVersion { get; set; }
    public string AppPoolState { get; set; }
    public string AppPoolIdentityType { get; set; }
    public string AppPoolUsername { get; set; }
    public string AppPoolPassword { get; set; }
    public string ComputerName { get; set; }
    public string AppPoolName { get; set; }
    public string AppPath { get; set; }
    public string EnabledProtocols { get; set; }
}
原文地址:https://www.cnblogs.com/sui84/p/13783093.html