我是学习PowerShell的新手,我一直在编写代码来执行以下操作:
现在,我输出了4&的结果。 5到文本文件,然后通过 Get-Content 导入它,但这不起作用,好像该文件尚不存在,它将无法正常工作。它似乎无法输出文件然后从中获取内容。我认为必须有某种方法来做,但我不确定。
我认为我没有正确循环 TrimStart 和 For-Each 命令。任何帮助将不胜感激。
$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()
}
答案 0 :(得分:1)
我不确定为什么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)
答案 1 :(得分:1)
我有一些建议可以帮助你编写脚本。
尝试将变量命名为自我描述的东西。当您逐行调试和逐步执行代码时,这将使故障排除变得更容易。
逐步编写代码。不要试图一次咬太多。如果您使用内嵌注释记录代码,将有助于您更有意义。
每次编写脚本时都使用参数名称,并且不要将位置参数视为理所当然。这将提高脚本的可读性。
限定所有文件系统路径。您永远不知道“工作目录”何时可能与脚本所在的目录不同。使用$PSScriptRoot
变量(首先在PowerShell v3.0中引入)来引用“包含脚本文件的文件夹。”
我之前没有测试过这段代码,因为我没有CSV文件的副本,但它应该可以帮助您了解更多内容。我也冒昧地整合了一些代码以使其更简单。
重要:确保您运行的是最新版本的PowerShell,即版本4.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()
}