你有没有必须多次执行相同任务的经历?比如,使用图形用户界面逐个创建多个Active Directory用户?或者登陆服务器来删除选定文件夹中的旧日志?如果你的答案是是的,那么你并不孤单。现在是时候掌握PowerShell的Import-Csv
和foreach循环了。
手动任务没有什么问题;有时是必要的。但是当涉及到读取和处理CSV文件时,PowerShell的Import-Csv
命令和ForEach
循环可以帮助你。
PowerShell的Import-Csv
命令是从表格化源(如CSV文件)读取数据的一种绝佳方法。然后,你可以使用ForEach
循环遍历CSV数据中的每一行。
在本文中,你将学习如何使用这个强大的组合来自动化大批量、单调和重复的任务。
如果你对
Import-Csv
命令和ForEach
循环还不熟悉,或者想要回顾一下你已经了解的内容,你可以访问以下链接了解更多信息。
先决条件
本文中有几个示例和演示。为了跟上,你首先需要一些东西。
- A script editor such as Visual Studio Code, Atom, or Notepad++. Use whichever one you’re comfortable with.
- Windows PowerShell 5.1或PowerShell Core 6+
- 访问Exchange Online(如果您将按照与Exchange Online相关的示例进行实践,则可选)。
将Import-Csv和ForEach循环付诸实践
下面是几个示例,演示如何使用Import-Csv
cmdlet和ForEach
循环,您可能会在实际场景中遇到。虽然这些导入CSV的PowerShell示例针对不同的目的,但重要的是要理解所采用的概念和技术是相同的。
从CSV中读取和显示记录
也许最基本的使用Import-Csv
和ForEach
循环的方法是从文件中读取记录并在控制台中显示它们。CSV文件的结构类似于数据库。它有列标题,每一行被视为一个记录。
例如,下面是名为employee.csv
的文件的内容,它包含三列 – EmployeeID,Name和Birthday,以及四个记录。

下面的代码导入employee.csv文件的内容,然后将导入的数据传递给ForEach-Object
cmdlet。然后,ForEach-Object
将遍历导入的CSV中的每个记录,将连接的值显示在控制台中。复制下面的代码并将其保存为list-employee.ps1。
注意:此示例中使用的ForEach循环类型是ForEach-Object cmdlet。请参考本文中的“ForEach-Object cmdlet”部分。
脚本保存后,通过在PowerShell中调用其文件名来运行它。运行脚本时,您应该会看到类似下面截图的输出。

搜索和显示CSV中的记录
在前面的示例中,您学习了如何读取和显示CSV中的所有记录。在这个示例中,将使用相同的CSV文件employee.csv,但这次您将创建一个PowerShell函数来搜索CSV中的EmployeeID。
下面的代码段是一个名为Find-Employee
的PowerShell函数,它只有一个参数。参数名称为EmployeeID
,它接受一个要从CSV中搜索的员工ID值。
在使用此函数之前,首先需要将其导入到您的PowerShell会话中。有两种方法可以将Find-Employee
函数导入到内存中:
- 将下面的代码复制并粘贴到PowerShell中。
- 将脚本保存为
Find-Employee.ps1
,并使用点号引用技术进行导入。
注意:在下面的示例中使用的ForEach循环类型是ForEach语句。请参阅本文中的“foreach语句”部分。
将函数代码导入到PowerShell会话后,通过键入函数名称来调用它,如下所示。
如果在不使用EmployeeID
参数的情况下运行该函数,它将提示输入要搜索的EmployeeID
的值。请参考下面的示例输出。

或者,可以在运行时指定EmployeeID参数值来运行该函数,如下所示。
从多个服务器获取磁盘空间使用情况
系统管理员常见的例行任务之一是监视多个服务器的磁盘空间使用情况。您可以创建一个包含服务器名称、驱动器字母和阈值的CSV列表。然后,使用PowerShell导入CSV文件并循环遍历每一行来运行查询。
要创建一个从远程服务器获取磁盘空间使用情况的脚本,首先创建包含以下标题的CSV列表:
- servername – 这是要查询的名称服务器。
- disk – 这是要检索空间使用情况的驱动器的字母。
- threshold – 这定义了以GB为单位的阈值。如果磁盘的可用空间低于此值,报告将显示警告状态。
下面的示例显示了四个记录。您的CSV文件将根据要读取的服务器或磁盘的数量而不同。
完成CSV文件后,将文件保存为
为了提供一个获取磁盘空间使用情况的示例,将下面的代码复制到脚本编辑器中,并将其保存为
上述脚本在执行时执行以下操作。
- 导入名为
的csv文件,并将其存储在 $server_list
变量中。 - 循环遍历存储在
$server_list
变量中的服务器列表。 - 在每次foreach循环的迭代中,当前行由变量
$server
表示。 - 使用
Get-WmiObject
命令获取服务器的磁盘信息。 - 選擇只顯示相關屬性。
– 伺服器名稱 – 這是被查詢系統的名稱。
– 磁盤代號 – 指派給驅動器的字母。
– 大小 (GB) – 磁盤的大小,以GB為單位
– 可用空間 (GB) – 可用空間的大小,以GB為單位
– 閾值 (GB) – 定義的GB閾值
– 狀態 – 如果 可用空間 (GB) 的值低於 閾值 (GB) 的值,則返回的狀態是 ‘警告‘。否則,狀態將是 ‘正常‘
儲存了腳本檔案 diskReport.ps1 後,現在可以通過在PowerShell中調用其名稱來運行。
執行後,下面的截圖顯示了腳本的輸出。

輸出也可以導出到CSV。當需要共享報告時,導出到CSV很有用,因為導出的CSV檔案可以通過電子郵件發送,或上傳到檔案共享或SharePoint站點。如果您想了解更多關於導出到CSV的資訊,請務必查看 Export-Csv: PowerShell處理CSV檔案的方式。
創建多個Active Directory用戶
到目前為止,您應該已經對使用 Import-Csv
和 ForEach
有了堅實的了解。下一個示例通過加入 New-ADUser
和 Get-ADUser
Cmdlet,將您的學習進一步深入。
假設您收到一個名為 new_employees.csv
的 CSV 檔案,其中包含人力資源部門提供的新員工清單。CSV 檔案中的每一行代表一個待入職的使用者,並具有以下欄位:名字、姓氏、部門、州份、員工編號和辦公室。
使用者名稱必須由員工的名字的第一個字母連接姓氏而來(例如,對於使用者Bob Parr,使用者名稱應為bparr)。

保存 CSV 檔案後,下面的腳本使用Import-Csv
來讀取CSV檔案new_employees.csv。然後,迭代每一行,將值傳遞給New-ADUser
的相應參數。
執行腳本後,新使用者應已存在於Active Directory中。但是,確認是否真的已創建用戶帳戶是一種良好的做法。
使用相同的CSV檔案new_employees.csv作為參考,下面的腳本將運行import CSV和foreach,以獲取與清單中的對應的ADUser物件。
新增Proxy郵件地址到Office 365郵箱
在Office 365郵箱管理中,經常會收到添加多個使用者的代理地址的請求。通常,在此類請求中,管理員會收到一個使用者列表和要添加的電子郵件地址,類似於以下CSV示例。

注意: 在 PowerShell 中运行任何 Exchange Online 命令之前,您必须先登录Exchange Online 管理 shell。
使用 PowerShell 脚本中的 Import-Csv
和 ForEach
循环,可以一次处理列表。下面的脚本演示了如何操作。
下面的脚本将导入 new_address.csv 文件的内容并存储到 $user_list
变量中。然后,使用 foreach()
方法,PowerShell 循环遍历整个用户列表,并在每个记录中使用 username
和 email
的值来为每个邮箱添加一个新的电子邮件地址。
运行脚本后,控制台不会显示任何输出。没有屏幕输出意味着新的电子邮件地址已成功添加。但是,如何确保电子邮件地址已添加?
使用相同的 CSV 文件 new_address.csv 作为参考,可以使用 Import-Csv
和 ForEach
来验证新地址是否已添加。
下面的脚本将导入 new_address.csv 文件的内容并存储到 $user_list
变量中。然后,使用 foreach()
方法,PowerShell 循环遍历整个用户列表,检查新的电子邮件地址是否存在于邮箱代理地址列表中。如果找到,则状态将返回 True;否则,结果将是 False。
當驗證腳本運行時,輸出應該與下面的屏幕截圖一樣。你會注意到下面的輸出中,狀態都是 TRUE,這意味著新的郵件地址已成功添加到每個郵箱中。

發送每日天氣預報給郵件列表
在這個例子中,假設你有一個包含訂閱者的郵件地址和他們的地區或位置的 CSV 文件。這些訂閱者希望每天收到一封包含當天特定地區天氣預報的電子郵件。請查看下面的樣本 CSV 文件,文件名為 subscribers.csv。

下面的 CSV 文件只包含兩個訂閱者。一個在 洛杉磯,一個在 馬尼拉。
目標是創建一個腳本執行以下操作:
- 從 subscribers.csv 文件中導入郵件和地區信息
- 對於每個訂閱者:
– 從 https://wttr.in/ 下載基於訂閱者所在地區的天氣預報圖片
– 把天氣預報圖片作為電子郵件發送給訂閱者的郵件地址。
下面的腳本執行上述操作。你只需要修改前三個變量 – $senderAddress
、$smtpServer
和 $smtpPort
。然後,複製這段代碼並保存為 Send-WeatherInfo.ps1
。請參考腳本各個部分上方的注釋以了解代碼的功能。
運行腳本後,將向每個訂閱者發送類似於下面示例電子郵件截圖的電子郵件。


總結
使用Import-Csv
和ForEach
循環的任務沒有限制。只要任務涉及具有分隔列的列表,您肯定會使用這個強大的組合。
在本文中,您已經了解了CSV文件與數據庫的相似之處。您還學會了如何使用Import-Csv
導入數據,以及如何在ForEach
循環迭代期間引用這些值。
I hope that with the many examples provided in this article, you now understand more of the Import-Csv
and ForEach
. And, that you would be able to use the knowledge you gained in this article in your administration and automation tasks.
進一步閱讀
Source:
https://adamtheautomator.com/import-csv-and-the-foreach-loop/