Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Powershell 多行上的TrimStart/ForEach_Powershell - Fatal编程技术网

Powershell 多行上的TrimStart/ForEach

Powershell 多行上的TrimStart/ForEach,powershell,Powershell,我是学习PowerShell的新手,我一直在编写代码来执行以下操作: 从CSV文件导入计算机列表 将计算机从文件中的旧名称重命名为文件中的新名称 抓取重命名的每台计算机上当前登录的用户 删除用户名的开头部分(“CompanyName\”) 在行尾添加“@company.com” 将该数据设置为变量 将该变量用作编程电子邮件中的电子邮件地址 发送上述电子邮件 现在,我让它将4和5的结果输出到一个文本文件,然后通过获取内容导入它,但这不起作用,因为如果该文件不存在,它就不起作用。它似乎无法输出文件,

我是学习PowerShell的新手,我一直在编写代码来执行以下操作:

  • 从CSV文件导入计算机列表
  • 将计算机从文件中的旧名称重命名为文件中的新名称
  • 抓取重命名的每台计算机上当前登录的用户
  • 删除用户名的开头部分(“CompanyName\”)
  • 在行尾添加“@company.com”
  • 将该数据设置为变量
  • 将该变量用作编程电子邮件中的电子邮件地址
  • 发送上述电子邮件
  • 现在,我让它将4和5的结果输出到一个文本文件,然后通过获取内容导入它,但这不起作用,因为如果该文件不存在,它就不起作用。它似乎无法输出文件,然后从中获取内容。我想一定有办法,但我不确定

    我认为我没有为每个
    命令正确循环TrimStart。任何帮助都将不胜感激

    $Cred = Get-Credential
    $Import = Import-CSV Rename.csv -Header OldName, NewName
        ForEach ( $Machine in $Import ) {Rename-Computer -ComputerName $Machine.OldName -NewName $Machine.NewName -DomainCredential $Cred -whatif -Verbose}
    $a = ForEach ( $User in $MachineList ){
        (Get-WmiObject -ComputerName $User.OldName -Namespace root\cimv2 -Class Win32_ComputerSystem)[0].UserName;
        }
    $b = $a.TrimStart("CompanyName\") | ForEach {$_+'@Company.com'} | Out-File names.txt
    $Address = Get-Content names.txt 
    ForEach ($line in $Address) {
        $Outlook = New-Object -ComObject Outlook.Application
        $Mail = $Outlook.CreateItem(0)
        $Mail.To = "$Address"
        $Mail.Subject = "Please restart your computer"
        $Mail.HTMLBody = Get-Content RenameComputerEmail.htm
        $Mail.Send()
        }
    

    我不确定为什么
    Out File
    不起作用,但我建议采用如下方法。请注意,我以前没有使用过
    outlook.application
    ,因此我不能保证代码不经过调整就能正常工作

    $Cred = Get-Credential
    $Import = Import-CSV Rename.csv -Header OldName, NewName
    
    $Addresses = @()
    
    #Rename each computer and get the username
    ForEach ( $Machine in $Import ) {
        $Comp = Get-WmiObject -ComputerName $User.OldName -Class "Win32_ComputerSystem"
        $Usermail = "$($Comp.UserName.Split("\")[-1])@Company.com"
        $Addresses += $Usermail
    
        Rename-Computer -ComputerName $Machine.OldName -NewName $Machine.NewName -DomainCredential $Cred -whatif -Verbose
        #Don't bother saving the names and then reloading. (unless it's for logging)
    } 
    
    #Create one instance of outlook
    $Outlook = New-Object -ComObject Outlook.Application
    
    #Send mails to each address
    ForEach ($address in $Addresses) {
        $Mail = $Outlook.CreateItem(0)
        $Mail.To = "$address"
        $Mail.Subject = "Please restart your computer"
        $Mail.HTMLBody = (Get-Content RenameComputerEmail.htm) -join "`n"
        $Mail.Send()
    }
    
    #Disposing the outlook object using all the methods just to be safe.
    $Outlook.Quit()
    [System.Runtime.Interopservices.Marshal]::ReleaseComObject($Mail)
    [System.Runtime.Interopservices.Marshal]::ReleaseComObject($Outlook)
    

    我不确定为什么
    Out File
    不起作用,但我建议采用如下方法。请注意,我以前没有使用过
    outlook.application
    ,因此我不能保证代码不经过调整就能正常工作

    $Cred = Get-Credential
    $Import = Import-CSV Rename.csv -Header OldName, NewName
    
    $Addresses = @()
    
    #Rename each computer and get the username
    ForEach ( $Machine in $Import ) {
        $Comp = Get-WmiObject -ComputerName $User.OldName -Class "Win32_ComputerSystem"
        $Usermail = "$($Comp.UserName.Split("\")[-1])@Company.com"
        $Addresses += $Usermail
    
        Rename-Computer -ComputerName $Machine.OldName -NewName $Machine.NewName -DomainCredential $Cred -whatif -Verbose
        #Don't bother saving the names and then reloading. (unless it's for logging)
    } 
    
    #Create one instance of outlook
    $Outlook = New-Object -ComObject Outlook.Application
    
    #Send mails to each address
    ForEach ($address in $Addresses) {
        $Mail = $Outlook.CreateItem(0)
        $Mail.To = "$address"
        $Mail.Subject = "Please restart your computer"
        $Mail.HTMLBody = (Get-Content RenameComputerEmail.htm) -join "`n"
        $Mail.Send()
    }
    
    #Disposing the outlook object using all the methods just to be safe.
    $Outlook.Quit()
    [System.Runtime.Interopservices.Marshal]::ReleaseComObject($Mail)
    [System.Runtime.Interopservices.Marshal]::ReleaseComObject($Outlook)
    

    我不确定为什么
    Out File
    不起作用,但我建议采用如下方法。请注意,我以前没有使用过
    outlook.application
    ,因此我不能保证代码不经过调整就能正常工作

    $Cred = Get-Credential
    $Import = Import-CSV Rename.csv -Header OldName, NewName
    
    $Addresses = @()
    
    #Rename each computer and get the username
    ForEach ( $Machine in $Import ) {
        $Comp = Get-WmiObject -ComputerName $User.OldName -Class "Win32_ComputerSystem"
        $Usermail = "$($Comp.UserName.Split("\")[-1])@Company.com"
        $Addresses += $Usermail
    
        Rename-Computer -ComputerName $Machine.OldName -NewName $Machine.NewName -DomainCredential $Cred -whatif -Verbose
        #Don't bother saving the names and then reloading. (unless it's for logging)
    } 
    
    #Create one instance of outlook
    $Outlook = New-Object -ComObject Outlook.Application
    
    #Send mails to each address
    ForEach ($address in $Addresses) {
        $Mail = $Outlook.CreateItem(0)
        $Mail.To = "$address"
        $Mail.Subject = "Please restart your computer"
        $Mail.HTMLBody = (Get-Content RenameComputerEmail.htm) -join "`n"
        $Mail.Send()
    }
    
    #Disposing the outlook object using all the methods just to be safe.
    $Outlook.Quit()
    [System.Runtime.Interopservices.Marshal]::ReleaseComObject($Mail)
    [System.Runtime.Interopservices.Marshal]::ReleaseComObject($Outlook)
    

    我不确定为什么
    Out File
    不起作用,但我建议采用如下方法。请注意,我以前没有使用过
    outlook.application
    ,因此我不能保证代码不经过调整就能正常工作

    $Cred = Get-Credential
    $Import = Import-CSV Rename.csv -Header OldName, NewName
    
    $Addresses = @()
    
    #Rename each computer and get the username
    ForEach ( $Machine in $Import ) {
        $Comp = Get-WmiObject -ComputerName $User.OldName -Class "Win32_ComputerSystem"
        $Usermail = "$($Comp.UserName.Split("\")[-1])@Company.com"
        $Addresses += $Usermail
    
        Rename-Computer -ComputerName $Machine.OldName -NewName $Machine.NewName -DomainCredential $Cred -whatif -Verbose
        #Don't bother saving the names and then reloading. (unless it's for logging)
    } 
    
    #Create one instance of outlook
    $Outlook = New-Object -ComObject Outlook.Application
    
    #Send mails to each address
    ForEach ($address in $Addresses) {
        $Mail = $Outlook.CreateItem(0)
        $Mail.To = "$address"
        $Mail.Subject = "Please restart your computer"
        $Mail.HTMLBody = (Get-Content RenameComputerEmail.htm) -join "`n"
        $Mail.Send()
    }
    
    #Disposing the outlook object using all the methods just to be safe.
    $Outlook.Quit()
    [System.Runtime.Interopservices.Marshal]::ReleaseComObject($Mail)
    [System.Runtime.Interopservices.Marshal]::ReleaseComObject($Outlook)
    

    我有一些建议可以帮助你写剧本

    变量命名 尝试将变量命名为自描述性的名称。当您逐行调试和逐步浏览代码时,这将使故障排除变得更容易

    编写代码 一步一步地编写代码。不要一次咬得太多。如果您用行内注释来记录代码,它将帮助您理解代码

    参数名 在编写脚本时,请随时使用参数名称,不要想当然地使用位置参数。这将提高脚本的可读性

    文件系统路径 限定所有文件系统路径。您永远不知道您的“工作目录”何时可能与脚本所在的目录不同。使用
    $PSScriptRoot
    变量(首次在PowerShell v3.0中引入)引用“脚本文件的包含文件夹”

    解决方案 我没有在下面测试这段代码,因为我没有您的CSV文件的副本,但它应该可以帮助您进一步了解发生了什么。我还冒昧地整合了一些代码,使之更简单

    重要信息:确保运行的是最新版本的PowerShell,即4.0版。3.0将是一个可接受的替代方案,但任何早于3.0的功能都会受到相当大的限制。您可以通过键入
    $PSVersionTable
    来确定正在运行的版本

    #requires -version 3.0
    
    # 1. Get administrative credential
    $Cred = Get-Credential;
    
    # 2. Import the CSV file
    $Import = Import-CSV -Path $PSScriptRoot\Rename.csv -Header OldName, NewName;
    
    # 3. Rename each computer
    $Import | % { Rename-Computer -ComputerName $PSItem.OldName -NewName $PSItem.NewName -DomainCredential $Cred -WhatIf -Verbose; };
    
    # 4. Get username from each, remote computer, and write to names.txt
    $Import.OldName | ForEach-Object -Process { (Get-WmiObject -ComputerName $PSItem -Namespace root\cimv2 -Class Win32_ComputerSystem).UserName.TrimStart('CompanyName\') + '@companyname.com'; } | Out-File -FilePath $PSScriptRoot\names.txt;
    
    # 5. Get all of the usernames
    $Address = Get-Content -Path $PSScriptRoot\names.txt;
    
    # 6. Send e-mail to each user
    $Outlook = New-Object -ComObject Outlook.Application;
    ForEach ($line in $Address) {
        $Mail = $Outlook.CreateItem(0)
        $Mail.To = "$Address"
        $Mail.Subject = "Please restart your computer"
        $Mail.HTMLBody = Get-Content RenameComputerEmail.htm
        $Mail.Send()
        }
    

    我有一些建议可以帮助你写剧本

    变量命名 尝试将变量命名为自描述性的名称。当您逐行调试和逐步浏览代码时,这将使故障排除变得更容易

    编写代码 一步一步地编写代码。不要一次咬得太多。如果您用行内注释来记录代码,它将帮助您理解代码

    参数名 在编写脚本时,请随时使用参数名称,不要想当然地使用位置参数。这将提高脚本的可读性

    文件系统路径 限定所有文件系统路径。您永远不知道您的“工作目录”何时可能与脚本所在的目录不同。使用
    $PSScriptRoot
    变量(首次在PowerShell v3.0中引入)引用“脚本文件的包含文件夹”

    解决方案 我没有在下面测试这段代码,因为我没有您的CSV文件的副本,但它应该可以帮助您进一步了解发生了什么。我还冒昧地整合了一些代码,使之更简单

    重要信息:确保运行的是最新版本的PowerShell,即4.0版。3.0将是一个可接受的替代方案,但任何早于3.0的功能都会受到相当大的限制。您可以通过键入
    $PSVersionTable
    来确定正在运行的版本

    #requires -version 3.0
    
    # 1. Get administrative credential
    $Cred = Get-Credential;
    
    # 2. Import the CSV file
    $Import = Import-CSV -Path $PSScriptRoot\Rename.csv -Header OldName, NewName;
    
    # 3. Rename each computer
    $Import | % { Rename-Computer -ComputerName $PSItem.OldName -NewName $PSItem.NewName -DomainCredential $Cred -WhatIf -Verbose; };
    
    # 4. Get username from each, remote computer, and write to names.txt
    $Import.OldName | ForEach-Object -Process { (Get-WmiObject -ComputerName $PSItem -Namespace root\cimv2 -Class Win32_ComputerSystem).UserName.TrimStart('CompanyName\') + '@companyname.com'; } | Out-File -FilePath $PSScriptRoot\names.txt;
    
    # 5. Get all of the usernames
    $Address = Get-Content -Path $PSScriptRoot\names.txt;
    
    # 6. Send e-mail to each user
    $Outlook = New-Object -ComObject Outlook.Application;
    ForEach ($line in $Address) {
        $Mail = $Outlook.CreateItem(0)
        $Mail.To = "$Address"
        $Mail.Subject = "Please restart your computer"
        $Mail.HTMLBody = Get-Content RenameComputerEmail.htm
        $Mail.Send()
        }
    

    我有一些建议可以帮助你写剧本

    变量命名 尝试将变量命名为自描述性的名称。当您逐行调试和逐步浏览代码时,这将使故障排除变得更容易

    编写代码 一步一步地编写代码。不要一次咬得太多。如果您用行内注释来记录代码,它将帮助您理解代码

    参数名 在编写脚本时,请随时使用参数名称,不要想当然地使用位置参数。这将提高脚本的可读性

    文件系统路径 限定所有文件系统路径。您永远不知道您的“工作目录”何时可能与脚本所在的目录不同。使用
    $PSScriptRoot
    变量(首次在PowerShell v3.0中引入)引用脚本文件的“包含文件夹”