i'm new to ps scripting , i want to export certain data from event logs. I tried following
$Myexcel = New-Object -ComObject excel.application
$Myexcel.visible = $true
$Myworkbook = $Myexcel.workbooks.add()
$Sheet1 = $Myworkbook.worksheets.item(1)
$Sheet1.name = "summary"
$Sheet1.cells.item(1,1) = 'BootDevice'
$events = Get-WinEvent -FilterHashtable #{logname="Microsoft-Windows-Storage-Storport/Health"; id=511}
# get the first event raw XML
$event = [xml]$events[0].ToXml()
# display its content
#$event.Event.EventData.Data
$BootDevice=$event.Event.EventData.Data | Where-Object {$_.name -eq "BootDevice"}
write-output $BootDevice
$Sheet1.cells.item(2,1) = $BootDevice
$Sheet1.Columns.AutoFit()
$Myfile = 'E:\tmp\test.xlsx'
$Myworkbook.Saveas($Myfile)
$Myexcel.displayalerts = $true
But its giving error
Exception from HRESULT: 0x800A03EC
At line:16 char:1
+ $Sheet1.cells.item(2,1) = $BootDevice
And a blank excel is generated.
Any help will be thankfull.
I am about to create a detailed report of all site collections on a tenant.
One part of the report is the usage data such as hits & visits. The report always returns 0 for these properties. I thought there might be a delay between the actual hit/visit and the report, so I tried it several times.
Here is my script:
$adminSiteUrl = "https://tenant-admin.sharepoint.com";
Connect-PnPOnline -Url $adminSiteUrl -Credentials 'O365Dev'
$sites = Get-PnPTenantSite -Detailed
Write-Host "Site Collections found: " $sites.Count
$siteDirectory = #()
foreach ($site in $sites)
{
$tenantSite = $sites | Where-Object {$_.Url -eq $site.Url}
$siteDirectoryEntry = New-Object psobject
Connect-PnPOnline -Url $site.Url -Credentials 'O365Dev'
$siteDetails = Get-PnPSite -Includes RootWeb.Created, RootWeb.SiteUsers, RootWeb.Webs, GeoLocation, IsHubSite, LockIssue, Owner, SecondaryContact, Usage; $siteDetails
$siteDirectoryEntryProperties = #{
URL = $siteDetails.Url
Title = $tenantSite.Title
Description = $tenantSite.Description
...
UsageBandwidth = $siteDetails.Usage.Bandwidth
UsageHits = $siteDetails.Usage.Hits
UsageVisits = $siteDetails.Usage.Visits
}
$siteDirectoryEntry = New-Object psobject -Property $siteDirectoryEntryProperties
$siteDirectory += $siteDirectoryEntry
}
$siteDirectory | Export-Csv .\SiteDirectory.csv
I also tried to add "Usage.Hits" to the "Includes" argument of Get-PnPSite as I would do with other properties such as RootWeb. While it works for the latter, it throws the following error for any UsageInfo Properties:
Get-PnPSite : The query expression is not supported.
At C:\Users....\SPO_Reports.ps1:19 char:20
+ ... teDetails = Get-PnPSite -Includes RootWeb.Created, RootWeb.SiteUsers, ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : WriteError: (:) [Get-PnPSite], InvalidQueryExpressionException
+ FullyQualifiedErrorId : EXCEPTION,SharePointPnP.PowerShell.Commands.Site.GetSite
I know I can get some usage statistics like storage through Get-PnPTenantSite but when it comes to hits and visits, it seems like this would be the only way.
Any ideas what I am doing wrong?
Reply by MS Support-
At this time, the only supported method to display usage data for SharePoint Online is through the GUI. You can find more information about this here: https://support.office.com/en-us/article/view-usage-data-for-your-sharepoint-site-2fa8ddc2-c4b3-4268-8d26-a772dc55779e
The information above is not acceptable
I just recently joined an IAM team, and this month had to send out hundreds of emails to people notifying them of an account expiration (they are asked to either request for an extension or termination of the account). Thankfully, there's already a script made to do that part, but for dealing with the responses there is not. There's an excel spreadsheet where I record what is to happen to each account. I was hoping to make a script that can go through each of the responses and mark in the desired field in the spreadsheet accordingly. I've been having trouble with the part of the script where I modify the value under the desired field for the user.
I'm fairly new to PowerShell, so I'm not sure what the issue is. I already spent a few hours looking online and found quite a few possible solutions, but none of them have worked for me. A common problem is apparently using an older excel file, but it's fresh and it's Excel 2016. Another one is not having the correct file type, but I checked and that's not it either. The line of code in question is $extend.Cells.Item($modifyCell.Cells.Row) = "$data".
Any ideas what the problem could be?
Code:
# Path to .msg files
$msgDir = "C:\Users\me\Desktop\Test"
# Array to store results
$msgArray = New-Object System.Collections.Generic.List[object]
# Loop throuch each .msg file
Get-ChildItem "$msgDir" -Filter *.msg |
ForEach-Object {
# Open .msg file
$outlook = New-Object -comobject outlook.application
$msg = $outlook.Session.OpenSharedItem($_.FullName)
# Add .msg file Subject and Body to array
$msgArray.Add([pscustomobject]#{Subject=$msg.Subject;Body=$msg.Body;})
$msg.Close(0) # Close doesn't always work, see KB2633737 -- restart ISE/PowerShell
}
# Loop though / parse each message
ForEach ($message in $msgArray) {
$subject = $message.subject
$body = $message.body
$regex = [regex] '\s*(\w*)\s*\|$'
If ($body -match $regex) {
$username = $body
}
$parse = $body | Select-String -Pattern "Please extend"
If ($parse -eq "Please extend") {
$data = "Y"
}
}
# Open Excel
$Excel = New-Object -ComObject Excel.Application
$Excel.Visible = $True
$OpenFile = $Excel.Workbooks.Open("C:\Users\me\Desktop\test.xlsx")
$Workbook = $OpenFile.Worksheets
$Worksheet = $Workbook.Item(1)
# Get the values for each column
$samacctname = $Worksheet.Cells | where {$_.value2 -eq "SAM Account Name"} | select -First 1
$extend = $Worksheet.Cells | where {$_.value2 -eq "Extend"} | select -First 1
# Get the values for each row in SAM Account Name
$userValues = #()
for($i=2; $samacctname.Cells.Item($i).Value2 -ne $null; $i++ ){
$userValues += $samacctname.Cells.Item($i)
}
# Get the values where the cell value of SAM Account matches the username
$modifyCell = $userValues | where {$_.Value2 -eq $username}
# Modify the Extend cell using the username's row position
$extend.Cells.Item($modifyCell.Cells.Row) = "$data"
# Save the file
$OpenFile.Save()
Edit 1: I went back into my code and first tried to hard-code the data value I was trying to add to the cell, but I still got the same error. I then tried hard-coding it right when I call the line $extend.Cells.Item($modifyCell.Cells.Row) = "Y" and it works as it should. So how I'm trying to use regex to pull the username is likely not right. Probably how I'm pulling the data as well.
Hello I'm trying to write a powershell script to run a query on an MS Access database and then exporting the table generated from the query to a excel file.
Here is my current Script, but the issue I'm running into is that all the data is being exported into one cell. I need every field item to be exported to its own column.
$DBFilePath ="D:\SFET_BuildVersion\CurrencyReport\ClientBuildVersions.accdb"
$adOpenStatic = 3
$adLockOptimistic = 3
$infoColl = #()
$conn=New-Object -com "ADODB.Connection"
$rs = New-Object -com "ADODB.Recordset"
$conn.Open("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=$DBFilePath; Persist Security Info=False;")
$rs.Open("SELECT * from SFClient",$conn,$adOpenStatic,$adLockOptimistic)
$rs.MoveFirst()
$myOuput = While ( ! $rs.EOF ) {
New-Object -TypeName PSObject -Property #{
Customer = $rs.Fields.Item('Customer').Value
HHRR = $rs.Fields.Item('HHRR').Value
System = $rs.Fields.Item('System').Value
Release_Level = $rs.Fields.Item('Release Level').Value
TNTAL_version = $rs.Fields.Item('TNTAL version').Value
HF_Level = $rs.Fields.Item('HF Level').Value
Createdate = $rs.Fields.Item('Createdate').Value
CLAIMS_version = $rs.Fields.Item('CLAIMS version').Value
CreatedateC = $rs.Fields.Item('CreatedateC').Value
PayerRules_version = $rs.Fields.Item('PayerRules version').Value
ECV_Version = $rs.Fields.Item('ECV Version').Value
Edits = $rs.Fields.Item('Edits').Value
REGs_version = $rs.Fields.Item('REGs version').Value
BBM = $rs.Fields.Item('BBM version').Value
OMS_version = $rs.Fields.Item('OMS version').Value
Runtime = $rs.Fields.Item('Runtime').Value
HASvr = $rs.Fields.Item('HASvr').Value
EOS = $rs.Fields.Item('EOS').Value
CurrencyDays = $rs.Fields.Item('Currency Days').Value
}
$rs.MoveNext()
}
$conn.Close
$rs.Close
$myOuput | FT -a
$myOuput | Out-GridView
$myOuput | Export-csv D:\SFET_BuildVersion\CurrencyReport\SFClient.xlsx -NoTypeInformation
I have a powershell script that reads in a csv and then appends to an excel worksheet.
It runs quite painfully slow. I have searched and it seems this is a limitation of using com to write to excel. Some suggestions I have found to speed this up are to write out entire ranges instead of cell by cell. However I need to format the cells and it doesn't seem to be possible to do this when writing out ranges. Any suggestions on how to optimize the below code would be welcome.
I do not have the option to use a DB.
$csvPath = "Z:\script_test\"
$outputFile = "Z:\script_test\exceltest.xlsx"
foreach($csvFile in Get-ChildItem $csvPath -Filter "STATS*.txt" ){
$csvFilePath = [io.path]::combine($csvPath, $csvFile)
$rawcsvData = Import-Csv -Delimiter ";" -Path $csvFilePath
$Excel = New-Object -ComObject excel.application
$Excel.visible = $false
$workbook = $Excel.workbooks.Open($outputFile)
$ExcelWorkSheet = $Excel.WorkSheets.item("2016")
$ExcelWorkSheet.activate()
$excel.cells.item(1,1) = “PEX”
$excel.cells.item(1,2) = “RUN DATE”
$excel.cells.item(1,3) = “EXECS”
$excel.cells.item(1,4) = “CPU AV.”
$excel.cells.item(1,5) = “CPU HI.”
$excel.cells.item(1,6) = “CPU TOT.”
$excel.cells.item(1,7) = “#VALUE!”
$excel.cells.item(1,8) = “ELAPS AV.”
$excel.cells.item(1,9) = “ELAPSE HI.”
$excel.cells.item(1,10) = “ELAPSE TOT”
$i = $ExcelWorkSheet.UsedRange.rows.count + 1
foreach($rawcsv in $rawcsvData)
{
$RUNDATE = $rawcsv.“RUN DATE ”.replace("--1","")
$EXECS = $rawcsv."EXECS ".replace("?","")
$CPUAV = $rawcsv.“CPU AV. ”.replace("-",":")
$CPUHI = $rawcsv.“CPU HI. ”.replace("-",":")
$CPUTOT = $rawcsv.“CPU TOT. ”.replace("-",":")
$ELAPSEAV = $rawcsv.“ELAPSE AV.”.replace("-",":")
$ELAPSEHI = $rawcsv.“ELAPSE HI.”.replace("-",":")
$ELPASETOT = $rawcsv.“ELPASE TOT”.replace("-",":")
Write-Output("working" + $i)
$excel.cells.item($i,1) = $rawcsv."PEX "
$excel.cells.item($i,2) = $RUNDATE
$excel.cells.item($i,2).NumberFormat = “yyyy/mm/dd”
$excel.cells.item($i,3) = $EXECS
$excel.cells.item($i,4) = $CPUAV
$excel.cells.item($i,4).NumberFormat = “hh:mm:ss.00”
$excel.cells.item($i,5) = $CPUHI
$excel.cells.item($i,5).NumberFormat = “hh:mm:ss.00”
$excel.cells.item($i,6) = $CPUTOT
$excel.cells.item($i,6).NumberFormat = “hh:mm:ss.00”
$excel.cells.item($i,7) = “=((HOUR(F"+$i+")*3600)+(MINUTE(F"+$i+")*60)+SECOND(F"+$i+"))*21”
$excel.cells.item($i,8) = $ELAPSEAV
$excel.cells.item($i,8).NumberFormat = “hh:mm:ss.00”
$excel.cells.item($i,9) = $ELAPSEHI
$excel.cells.item($i,9).NumberFormat = “hh:mm:ss.00”
$excel.cells.item($i,10) = $ELPASETOT
$excel.cells.item($i,10).NumberFormat = “hh:mm:ss.00”
$i++
}
$ExcelWorkSheet.UsedRange.RemoveDuplicates()
#$workbook.saveas($outputFile)
$workbook.save()
$Excel.Quit()
Remove-Variable -Name excel
[gc]::collect()
[gc]::WaitForPendingFinalizers()
Move-Item -Path $csvFilePath -Destination "Z:\script_test\used files"
}
The slow part is all about COM object performance. You won't be able to speed this up good enough if you will keep working with COM object, sadly.
Back in days I had some project related to Excel and I found some great module that uses external DLL, you can take a look on it: PSExcel
Best part is that you will not need to have Excel installed, like you do with COM object.
There is a Powershell cmdlet you can install called Export-XLSX that works very similarly to the native Export-CSV: https://gallery.technet.microsoft.com/office/Export-XLSX-PowerShell-f2f0c035
The documentation there is pretty good, but here's an example of how you would use it:
# 1. Define path of Export-XLSX.ps1 script:
$ExportXLSX = "C:\YourFilePath\Export-XLSX\Export-XLSX.ps1"
# 2. Call script same as any other function by preceding filename with a period (.$ExportXLSX) and following it with parameters:
Get-ChildItem $env:windir | Select-Object Mode,LastWriteTime,Length,Name | .$ExportXLSX -Path 'c:\temp\PSExcel.xlsx' -WorkSheetName 'Files'
UPDATE: Having compared this option with the full PSExcel module presented in the other answer, I actually prefer the PSExcel module. The performance speed-wise is pretty much the same in my testing, but the PSExcel module appears to create much smaller files.
For example, using the above list of the windows directory outputs a 53KB file using the Export-XLSX.ps1 on my machine. However, the PSExcel module outputs a 7KB file. Given its ease of use, I would go with it.