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