In this article we’ll show how to read and write data from Excel worksheets directly from PowerShell scripts. You can use Excel along with PowerShell to inventory and generate various reports on computers, servers, infrastructure, Active Directory, etc.
Before showing how to access data in an Excel cell, it is worth to understand the architecture of presentation layers in the Excel file. The figure below shows 4 nested presentation layers in the Excel object model:
- Application Layer – deals with the running Excel app;
- WorkBook Layer – multiple workbooks (Excel files) may be open at the same time;
- WorkSheet Layer – each XLSX file can contain several sheets;
- Range Layer – here you can access data in the specific cell or cell range.
How to Read Data from an Excel Spreadsheet using PowerShell?
Let’s take a look at a simple example of how to use PowerShell to access data in an Excel file containing a list of employees.
First, run the Excel app (application layer) on your computer using the COM object:
$ExcelObj = New-Object -comobject Excel.Application
After running the command, Excel will be launched on your computer in the background. To show the Excel window, change the Visible property of the COM object:
$ExcelObj.visible=$true
$ExcelObj| fl
Then you can open an Excel file (a workbook):
$ExcelWorkBook = $ExcelObj.Workbooks.Open("C:\PS\corp_ad_users.xlsx")
Each Excel file can contain several worksheets. Let’s display the list of worksheets in the current Excel workbook:
$ExcelWorkBook.Sheets| fl Name, index
Then you can open a sheet you want (by its name or index):
$ExcelWorkSheet = $ExcelWorkBook.Sheets.Item("CORP_users")
You can get the name of the current (active) Excel worksheet using this command:
$ExcelWorkBook.ActiveSheet | fl Name, Index
Then you can get values from cells in Excel worksheet. You can use different methods to get the cell values on the current Excel worksheet: using a range, a cell, a column or a row. See the examples of how to get data from the same cell below:
$ExcelWorkSheet.Range("B4").Text
$ExcelWorkSheet.Range("B4:B4").Text
$ExcelWorkSheet.Range("B4","B4").Text
$ExcelWorkSheet.cells.Item(4, 2).text
$ExcelWorkSheet.cells.Item(4, 2).value2
$ExcelWorkSheet.Columns.Item(2).Rows.Item(4).Text
$ExcelWorkSheet.Rows.Item(4).Columns.Item(2).Text
Exporting Active Directory User Info to Excel Spreadsheet using PowerShell
Let’s see a practical example of how to access Excel data from PowerShell. Suppose, we want to get some information from Active Directory for each user in an Excel file. For instance, their phone number (the telephoneNumber attribute), department and e-mail address .
# Importing Active Directory module into PowerShell session
import-module activedirectory
# Open an Excel workbook first:
$ExcelObj = New-Object -comobject Excel.Application
$ExcelWorkBook = $ExcelObj.Workbooks.Open("C:\PS\corp_ad_users.xlsx")
$ExcelWorkSheet = $ExcelWorkBook.Sheets.Item("CORP_Users")
# Get the number of filled in rows in the XLSX worksheet
$rowcount=$ExcelWorkSheet.UsedRange.Rows.Count
# Loop through all rows in Column 1 starting from Row 2 (these cells contain the domain usernames)
for($i=2;$i -le $rowcount;$i++){
$ADusername=$ExcelWorkSheet.Columns.Item(1).Rows.Item($i).Text
# Get the values of user attributes in AD
$ADuserProp = Get-ADUser $ADusername -properties telephoneNumber,department,mail|select-object name,telephoneNumber,department,mail
# Fill in the cells with the data received from AD
$ExcelWorkSheet.Columns.Item(4).Rows.Item($i) = $ADuserProp.telephoneNumber
$ExcelWorkSheet.Columns.Item(5).Rows.Item($i) = $ADuserProp.department
$ExcelWorkSheet.Columns.Item(6).Rows.Item($i) = $ADuserProp.mail
}
# Save the XLS file and close Excel
$ExcelWorkBook.Save()
$ExcelWorkBook.close($true)
As a result, the columns containing AD information have been added for each user in the Excel file.
Let’s consider another example of making a report using PowerShell and Excel. Suppose, you want to make an Excel report about Print Spooler service state on all domain servers.
# Create an Excel object
$ExcelObj = New-Object -comobject Excel.Application
$ExcelObj.Visible = $true
# Add a workbook
$ExcelWorkBook = $ExcelObj.Workbooks.Add()
$ExcelWorkSheet = $ExcelWorkBook.Worksheets.Item(1)
# Rename a worksheet
$ExcelWorkSheet.Name = 'Spooler Service Status'
# Fill in the head of the table
$ExcelWorkSheet.Cells.Item(1,1) = 'Server Name'
$ExcelWorkSheet.Cells.Item(1,2) = 'Service Name'
$ExcelWorkSheet.Cells.Item(1,3) = 'Service Status'
# Make the table head bold, set the font size and the column width
$ExcelWorkSheet.Rows.Item(1).Font.Bold = $true
$ExcelWorkSheet.Rows.Item(1).Font.size=15
$ExcelWorkSheet.Columns.Item(1).ColumnWidth=28
$ExcelWorkSheet.Columns.Item(2).ColumnWidth=28
$ExcelWorkSheet.Columns.Item(3).ColumnWidth=28
# Get the list of all Windows Servers in the domain
$computers = (Get-ADComputer -Filter 'operatingsystem -like "*Windows server*" -and enabled -eq "true"').Name
$counter=2
# Connect to each computer and get the service status
foreach ($computer in $computers) {
$result = Invoke-Command -Computername $computer –ScriptBlock { Get-Service spooler | select Name, status }
# Fill in Excel cells with the data obtained from the server
$ExcelWorkSheet.Columns.Item(1).Rows.Item($counter) = $result.PSComputerName
$ExcelWorkSheet.Columns.Item(2).Rows.Item($counter) = $result.Name
$ExcelWorkSheet.Columns.Item(3).Rows.Item($counter) = $result.Status
$counter++
}
# Save the report and close Excel:
$ExcelWorkBook.SaveAs('C:\ps\Server_report.xlsx')
$ExcelWorkBook.close($true)
You can use PowerShell to access Excel in a variety of scenarios. For example, you can create handy Active Directory reports or create PowerShell scripts to update AD data from Excel.
Set-ADUser
cmdlet, the employee can automatically update user info in AD (just delegate the employee the permissions to change AD user attributes and show how to run the PowerShell script). Thus you can keep an up-to-date address book with the relevant phone numbers, job titles and departments.
4 comments
It really got a lot of information access data by PowerShell. But when I increases the range by choosing multiple rows and columns by running below commands, it not showing what I expected as like tabular format.
$ExcelWorkSheet.Range(“B4”).Text
$ExcelWorkSheet.Range(“B4:B4”).Text
$ExcelWorkSheet.cells.Item(4, 2).text
$ExcelWorkSheet.Rows.Item(4).Columns.Item(2).Text
XXXX YYYY ZZZZ
AAAA BBBB CCCC
MMM NNNN PPPP
I experiences the same…
Honestly, this drives me CRAZY!!!!!!!
‘How to Read Data from an Excel Spreadsheet using PowerShell’ is NOT A QUESTION so PLEASE stop using a question mark at the end of the sentence
The question would be ‘How do I read data from an excel spreadsheet using PowerShell?’
Pls
How ad one rom using PowerShell with Excel
# My structure simple:
$path = “C:\\add-info-data.xlsx”
$excel = New-Object -Com Excel.Application
$excel.DisplayAlerts = $false
$wb = $excel.Workbooks.Open($path)
$ws = $wb.sheets.item(“MyData”)
$ws = $wb.ActiveSheet
$cells=$ws.Cells
# ???????
$row = $Ws.UsedRange.SpecialCells(1).row
$row = $row + 1
$col = 1
$ws.range($col,$row).text = “add-new.txt-1”
$ws.range($col+1,$row).text = “add-new.txt-2”
$ws.range($col+1,$row).text = “add-new.txt-3”
# Table month: for each days, from txt or ps1:
# show the txt eq col 1, row 1..3: add-new.txt-1, add-new.txt-2, add-new.txt-3 ……. add any moor …
# next day : idem
$wb.SaveAs(“C:\add-info-data-luna.xlsx”)
$wb.Close($true) | out-null # $false, $true to save
$excel.Quit()
$wb = $null
$wb = $null
[GC]::Collect()
# future
# clear-variable X* -scope global
thank for your help
Arnold