PNPUtil retrieve each driver and add to array with PSObject - arrays
Using Powershell I retrieve all third party drivers installed using:
$PNPDrivers = PNPUtil /Enum-Drivers
The format of the information retrieved are as followed:
Microsoft PnP Utility
Published Name: oem19.inf
Original Name: apollolakesystem.inf
Provider Name: INTEL
Class Name: Systemenheter
Class GUID: {4d36e97d-e325-11ce-bfc1-08002be10318}
Driver Version: 07/18/1968 10.1.17.1
Signer Name: Microsoft Windows Hardware Compatibility Publisher
Published Name: oem20.inf
Original Name: avotonsystem.inf
Provider Name: INTEL
Class Name: Systemenheter
Class GUID: {4d36e97d-e325-11ce-bfc1-08002be10318}
Driver Version: 07/18/1968 10.1.3.1
Signer Name: Microsoft Windows Hardware Compatibility Publisher
I'm trying to make a foreach loop so that each driver are added to an array with PSObject so that I can fetch required information later on in the script.
I have tried so many combinations but never succeeded.
Right now I have tried a regex expression and group each row in order to specify each value but I don't get any data what so ever.
Below is the Regex expression I have used which seems to work?
After that I've tried to follow the information from this link: Parsing Text with PowerShell
Just changing the information to match my code:
$Pattern = "
^(?<PublishedName>Published Name:.*)
^(?<OriginalName>Original Name:.*)
^(?<ProviderName>Provider Name:.*)
^(?<ClassName>Class Name:.*)
^(?<ClassGUID>Class GUID:.*)
^(?<DriverVersion>Driver Version:.*)
^(?<SignerName>Signer Name:.*)
"
$PNPDrivers |
Select-String -Pattern $Pattern |
Foreach-Object {
# here we access the groups by name instead of by index
$PublishedName, $OriginalName, $ProviderName, $ClassName, $ClassGUID, $DriverVersion, $SignerName = $_.Matches[0].Groups['PublishedName', 'OriginalName', 'ProviderName', 'ClassName', 'ClassGUID', 'DriverVersion', 'SignerName'].Value
[PSCustomObject] #{
PublishedName = $PublishedName
OriginalName = $OriginalName
ProviderName = $ProviderName
ClassName = $ClassName
ClassGUID = $ClassGUID
DriverVersion = $DriverVersion
SignerName = $SignerName
}
}
But no data is printed out so I must be missing some but I don't manage to find what.
How can I do to retrieve the data and for each driver use it?
Second try
The code below gives me all values (I think) but it splits it to one row each.
I guess this is because it doesn't match all rexeg:s at the same time.
Can this be changed?
$Pattern = "(^(?<PublishedName>^Published Name:\s*([^\n\r]*)))|(^(?<OriginalName>^Original Name:\s*([^\n\r]*)))|(^(?<ProviderName>^Provider Name:\s*([^\n\r]*)))|(^(?<ClassName>^Class Name:\s*([^\n\r]*)))|(^(?<ClassGUID>^Class GUID:\s*([^\n\r]*)))|(^(?<DriverVersion>^Driver Version:\s*([^\n\r]*)))|(^(?<SignerName>^Signer Name:\s*([^\n\r]*)))"
$PNPDrivers |
Select-String -Pattern $Pattern -AllMatch |
Foreach-Object {
# here we access the groups by name instead of by index
$PublishedName, $OriginalName, $ProviderName, $ClassName, $ClassGUID, $DriverVersion, $SignerName = $_.Matches[0].Groups['PublishedName', 'OriginalName', 'ProviderName', 'ClassName', 'ClassGUID', 'DriverVersion', 'SignerName'].Value
[PSCustomObject] #{
PublishedName = $PublishedName -replace "Published Name: ",""
OriginalName = $OriginalName -replace "Original Name: ",""
ProviderName = $ProviderName -replace "Provider Name: ",""
ClassName = $ClassName -replace "Class Name: ",""
ClassGUID = $ClassGUID -replace "Class GUID: ",""
DriverVersion = $DriverVersion -replace "Driver Version: ",""
SignerName = $SignerName -replace "Signer Name: ",""
}
}
Third try
Almost there! So close!
You are the man postanote!
Since I am going to loop through a package of drivers in our SCCM enviroment working with [PSCustomObject] seems to be the right way to do it.
Although the problem that persists seems to be that some rows get "out of sync" and displays wrong value for the column.
Any thoughts on how to correct that?
Fourth try
Working code!!
$List = New-Object System.Collections.ArrayList
((PNPUtil /Enum-Drivers |
Select-Object -Skip 2) |
Select-String -Pattern 'Published Name:' -Context 0,7) |
ForEach {
if($PSItem.Context.PostContext[4] -like "*Class Version:*"){
$ClassVersion = $PSItem.Context.PostContext[4] -replace '.*:\s+'
$DriverVersion = $PSItem.Context.PostContext[5] -replace '.*:\s+'
$SignerName = $PSItem.Context.PostContext[6] -replace '.*:\s+'
}else{
$ClassVersion = "N/A"
$DriverVersion = $PSItem.Context.PostContext[4] -replace '.*:\s+'
$SignerName = $PSItem.Context.PostContext[5] -replace '.*:\s+'
}
$y = New-Object PSCustomObject
$y | Add-Member -Membertype NoteProperty -Name PublishedName -value (($PSitem | Select-String -Pattern 'Published Name:' ) -replace '.*:\s+')
$y | Add-Member -Membertype NoteProperty -Name OriginalName -value (($PSItem.Context.PostContext[0]) -replace '.*:\s+')
$y | Add-Member -Membertype NoteProperty -Name ProviderName -value (($PSItem.Context.PostContext[1]) -replace '.*:\s+')
$y | Add-Member -Membertype NoteProperty -Name ClassName -value (($PSItem.Context.PostContext[2]) -replace '.*:\s+')
$y | Add-Member -Membertype NoteProperty -Name ClassGUID -value (($PSItem.Context.PostContext[3]) -replace '.*:\s+')
$y | Add-Member -Membertype NoteProperty -Name ClassVersion -value $ClassVersion
$y | Add-Member -Membertype NoteProperty -Name DriverVersion -value $DriverVersion
$y | Add-Member -Membertype NoteProperty -Name SignerName -value $SignerName
$z = $List.Add($y)
}
Let's say you only what monitors then you can just do this, without using a PSCustomObject at all.
Clear-Host
(PNPUtil /Enum-Drivers /class Display |
Select-Object -Skip 2) |
Select-String -Pattern 'Monitors' -Context 3,4
# Results
<#
Published Name: oem...
Original Name: tp...
Provider Name: L...
> Class Name: Monitors
Class GUID: {4d...
Driver Version: 11...
Signer Name: Micr...
Published Name: oe...
Original Name: tp...
Provider Name: L...
> Class Name: Monitors
Class GUID: {4d36...
Driver Version: 06...
Signer Name: Micros...
#>
# The cherry-pick as needed by index, string, string value, etc..
Clear-Host
((PNPUtil /Enum-Drivers /class Display |
Select-Object -Skip 2) |
Select-String -Pattern 'Monitors' -Context 3,4)[0]
# Results
<#
Published Name: oe...
Original Name: tpl...
Provider Name: L...
> Class Name: Monitors
Class GUID: {4d36e...
Driver Version: 11/...
Signer Name: Microso...
#>
Clear-Host
(PNPUtil /Enum-Drivers /class Display |
Select-Object -Skip 2 |
Select-String -Pattern 'Monitors' -Context 3,4 |
ForEach-Object {$PSItem.Context.PreContext[0]})
# Results
<#
Published Name: oem...
Published Name: oem...
#>
Clear-Host
(PNPUtil /Enum-Drivers /class Display |
Select-Object -Skip 2 |
Select-String -Pattern 'Monitors' -Context 3,4 |
ForEach-Object {$PSItem.Context.PreContext[0] -replace '.*:\s+'})
# Results
<#
oem...
oem...
#>
The above response is from a similar to this one that I and others have already responded to.
Parse pnputil output to published name for specific class
Are you guys in the same course/class, or in the same company doing the same thing to see who can get there first? ;-}
If You want to get just one driver's info at a time, just change that filter string and cherry-pick the line you are after.
Yet, if you really, really, want to use [PSCustomObject], then you can still use the above and refactor to this.
Clear-Host
((PNPUtil /Enum-Drivers /class Display |
Select-Object -Skip 2) |
Select-String -Pattern 'Class Name:' -Context 3,4) |
ForEach {
[PSCustomObject]#{
PublishedName = $PSItem.Context.PreContext[0] -replace '.*:\s+'
OriginalName = $PSItem.Context.PreContext[1] -replace '.*:\s+'
ProviderName = $PSItem.Context.PreContext[2] -replace '.*:\s+'
ClassName = ($PSitem | Select-String -Pattern 'Class Name:') -replace '.*:\s+'
ClassGUID = $PSItem.Context.PostContext[0] -replace '.*:\s+'
DriverVersion = $PSItem.Context.PostContext[1] -replace '.*:\s+'
SignerName = $PSItem.Context.PostContext[2] -replace '.*:\s+'
}
}
# Results
<#
PublishedName : oe...
OriginalName : am...
ProviderName : A...
ClassName : Syst...
ClassGUID : {4d36...
DriverVersion : 02/...
SignerName : Microso...
...
PublishedName : oem...
OriginalName : w...
ProviderName : W...
ClassName : W...
ClassGUID : {849...
DriverVersion : 11/...
SignerName : Microsof...
#>
Or table format:
Clear-Host
((PNPUtil /Enum-Drivers /class Display |
Select-Object -Skip 2) |
Select-String -Pattern 'Class Name:' -Context 3,4) |
ForEach {
[PSCustomObject]#{
PublishedName = $PSItem.Context.PreContext[0] -replace '.*:\s+'
OriginalName = $PSItem.Context.PreContext[1] -replace '.*:\s+'
ProviderName = $PSItem.Context.PreContext[2] -replace '.*:\s+'
ClassName = ($PSitem | Select-String -Pattern 'Class Name:') -replace '.*:\s+'
ClassGUID = $PSItem.Context.PostContext[0] -replace '.*:\s+'
DriverVersion = $PSItem.Context.PostContext[1] -replace '.*:\s+'
SignerName = $PSItem.Context.PostContext[2] -replace '.*:\s+'
}
} |
Format-Table -AutoSize
# Results
<#
PublishedName OriginalName ProviderName ClassName ClassGUID DriverVersion SignerName
------------- ------------ ------------ --------- --------- ------------- ----------
...
#>
Update as per your comment...
sometimes, some drivers apparently also displays a Class Version just
below Class GUID. When it does that row gets out of sync. Is it
possible to, I don't know, using a IF-statement that if PostContext[3]
exists change the order for the PostContext?
... and my response to it.
I played with this use case a bit more can refactored my code to address these potential custom/dynamic fields that can happen per driver.
On my system, I had two customer driver properties:
Extension ID
and
Class Version.
Context-wise, they in the same place, so, I addressed them that way. So, the code pulls the data and uses a custom field to hold the value of either or none. So, this means you need to first discover any such items, and alter the code as needed. Note: I used a Switch block to handle that and IF/then to finalize based on the fields needed in the case.
Clear-Host
# Parse/format PnpUtil output based on JSON details, customize for dynamic fields
$PNPDrivers = PNPUtil /Enum-Drivers
$StringDataRegEx = '.*:\s+'
$RemoveClassNamesRegEx = 'Extension ID|Class Version'
$CSvHeaders = #(
'PublishedName',
'OriginalName',
'ProviderName',
'ClassName',
'ClassGUID',
'ClassVersion_or_ExtensionGUID',
'DriverVersion',
'SignerName'
)
$ClassVersionElements = #(
'Extension ID',
'Class Version',
'Signer Name'
)
$ClassVersionElements |
ForEach {
$ElementString = $PSItem
$ContextID = If ($ElementString -match $RemoveClassNamesRegEx)
{5}
Else {6}
$PNPDrivers |
Select-String -Pattern $ElementString -Context $ContextID |
ForEach {
$DriverData = $PSItem
switch ($ElementString)
{
'Extension ID'
{
[PSCustomObject]#{
PublishedName = $DriverData.Context.PreContext[0] -replace $StringDataRegEx
OriginalName = $DriverData.Context.PreContext[1] -replace $StringDataRegEx
ProviderName = $DriverData.Context.PreContext[2] -replace $StringDataRegEx
ClassName = $DriverData.Context.PreContext[3] -replace $StringDataRegEx
ClassGUID = $DriverData.Context.PreContext[4] -replace $StringDataRegEx
ClassVersion_or_ExtensionID = (
$DriverData |
Select-String -Pattern $ElementString
) -replace $StringDataRegEx
DriverVersion = $DriverData.Context.PostContext[0] -replace $StringDataRegEx
SignerName = $DriverData.Context.PostContext[1] -replace $StringDataRegEx
}
}
'Class Version'
{
[PSCustomObject]#{
PublishedName = $DriverData.Context.PreContext[0] -replace $StringDataRegEx
OriginalName = $DriverData.Context.PreContext[1] -replace $StringDataRegEx
ProviderName = $DriverData.Context.PreContext[2] -replace $StringDataRegEx
ClassName = $DriverData.Context.PreContext[3] -replace $StringDataRegEx
ClassGUID = $DriverData.Context.PreContext[4] -replace $StringDataRegEx
ClassVersion_or_ExtensionID = (
$DriverData |
Select-String -Pattern $ElementString
) -replace $StringDataRegEx
DriverVersion = $DriverData.Context.PostContext[0] -replace $StringDataRegEx
SignerName = $DriverData.Context.PostContext[1] -replace $StringDataRegEx
}
}
'Signer Name'
{
If ($DriverData -NotMatch $RemoveClassNamesRegEx)
{
[PSCustomObject]#{
PublishedName = $DriverData.Context.PreContext[0] -replace $StringDataRegEx
OriginalName = $DriverData.Context.PreContext[1] -replace $StringDataRegEx
ProviderName = $DriverData.Context.PreContext[2] -replace $StringDataRegEx
ClassName = $DriverData.Context.PreContext[3] -replace $StringDataRegEx
ClassGUID = $DriverData.Context.PreContext[4] -replace $StringDataRegEx
ClassVersion_or_ExtensionID = 'Property not valid for this driver'
DriverVersion = $DriverData.Context.PreContext[5] -replace $StringDataRegEx
SignerName = (
$DriverData |
Select-String -Pattern $ElementString
) -replace $StringDataRegEx
}
}
}
}
}
} |
Format-Table -AutoSize
Related
Powershell error. WriteToServer. column does not allow DBNull.Value
I am using following powershell script to collect server storage information from multiple servers and into the one of the SQL server table. I am getting an error while executing following powershell script Error:- Exception calling "WriteToServer" with "1" argument(s): "Column 'server_name' does not allow DBNull.Value. Table has only one column with all server names in it. Powershell script grabs server name from database table and collect server storage information. It works for few servers however it fails for few server with above error. Table CREATE TABLE [dbo].[server_space_lku]( [server_name] [varchar](50) NOT NULL, CONSTRAINT [PK_server_lku] PRIMARY KEY CLUSTERED) I am using following powershell script. How can I fix the issue? param($destServer, $destDb) function Get-SqlData { param([string]$serverName=$(throw 'serverName is required.'), [string]$databaseName=$(throw 'databaseName is required.'), [string]$query=$(throw 'query is required.')) Write-Verbose "Get-SqlData serverName:$serverName databaseName:$databaseName query:$query" $connString = "Server=$serverName;Database=$databaseName;Integrated Security=SSPI;" $da = New-Object "System.Data.SqlClient.SqlDataAdapter" ($query,$connString) $dt = New-Object "System.Data.DataTable" [void]$da.fill($dt) $dt } #Get-SqlData function Get-Vol { param($computerName) Get-WmiObject -computername "$ComputerName" Win32_Volume -filter "DriveType=3 AND SystemVolume = $false" | foreach { add-member -in $_ -membertype noteproperty UsageDT $((Get-Date).ToString("yyyy-MM-dd")) add-member -in $_ -membertype noteproperty SizeGB $([math]::round(($_.Capacity/1GB),2)) add-member -in $_ -membertype noteproperty FreeGB $([math]::round(($_.FreeSpace/1GB),2)) add-member -in $_ -membertype noteproperty PercentFree $([math]::round((([float]$_.FreeSpace/[float]$_.Capacity) * 100),2)) -passThru} | select UsageDT, SystemName, Name, Label, SizeGB, FreeGB, PercentFree }# Get-Vol function Out-DataTable { param($Properties="*") Begin { $dt = new-object Data.datatable $First = $true } Process { $DR = $DT.NewRow() foreach ($item in $_ | Get-Member -type *Property $Properties ) { $name = $item.Name if ($first) { $Col = new-object Data.DataColumn $Col.ColumnName = $name $DT.Columns.Add($Col) } $DR.Item($name) = $_.$name } $DT.Rows.Add($DR) $First = $false } End { return #(,($dt)) } }# Out-DataTable function Write-DataTableToDatabase { param($destServer,$destDb,$destTbl,$dt) $connectionString = "Data Source=$destServer;Integrated Security=true;Initial Catalog=$destdb;" $bulkCopy = new-object ("Data.SqlClient.SqlBulkCopy") $connectionString $bulkCopy.DestinationTableName = "$destTbl" $bulkCopy.WriteToServer($dt) }# Write-DataTableToDatabase Get-SqlData $destServer $destDb "SELECT server_name FROM server_space_lku" | foreach { #Get just the server name portion if instance name is included $computerName = $_.server_name -replace "\\.*|,.*" $dt = Get-Vol $computerName | Out-DataTable Write-DataTableToDatabase $destServer $destDb 'vol_space' $dt }
Custom Object Export Array and Add to the array
I am having difficulty understanding what I am missing. I am trying to do 2 things, I am trying to build a custom object array, then later add to the custom object array with more data. Then Finally Export the full custom object array to a csv. I know I am close but all I am getting is "Object" for the custom object array. The object appears intact in Add-ArraySiteDefaultvsUserSettings and when it leave that function but then I can not build on the object and it be usefull. Function Add-DefaultsValidation { #New-Object psobject -Property #{IdenTity = '';SiteDefault = '';UserSetting = '';IssueAlert =''} $DefaultsObject = New-Object Object -TypeName PSObject Add-Member -MemberType NoteProperty -Name SiteCode -Value "" -InputObject $DefaultsObject Add-Member -MemberType NoteProperty -Name Identity -Value "" -InputObject $DefaultsObject Add-Member -MemberType NoteProperty -Name OU -Value "" -InputObject $DefaultsObject Add-Member -MemberType NoteProperty -Name SiteDefault -Value "" -InputObject $DefaultsObject Add-Member -MemberType NoteProperty -Name UserSetting -Value "" -InputObject $DefaultsObject Add-Member -MemberType NoteProperty -Name IssueAlert -Value "" -InputObject $DefaultsObject $DefaultsObject } Function Add-ArraySiteDefaultvsUserSettings { Param ( $OU, $Identity, $SiteCode, $SiteDefaultValue, $UserCurrentSettings, $AlertType ) #SiteDefaultvsUserSettings [array]$DefaultvsUserSettings = #() $addObject = Add-DefaultsValidation $addObject.SiteCode = $SiteCode $addObject.Identity = $Identity $addObject.OU = $OU $addObject.SiteDefault = $SiteDefaultValue $addObject.UserSetting = $UserCurrentSettings $addObject.IssueAlert = $AlertType $DefaultvsUserSettings += $addObject #Write-Output $SiteDefaultvsUserSettings Return $DefaultvsUserSettings } foreach ($SkypeSiteDefault in $SkypeSiteDefaults) { if ($SkypeSiteDefault.OU -ne $null) { $SkypeSiteDefault.'Site Code' $SkypeSiteDefault.RegistrarPool $SkypeUsersRegistrarInvalid = Get-CsUser -ResultSize unlimited -ou $SkypeSiteDefault.OU | Where-Object {$_.RegistrarPool.FriendlyName -notlike "*$($SkypeSiteDefault.RegistrarPool)*"} | Select SamAccountName, Registrarpool if ($SkypeUsersRegistrarInvalid.count -ne 0) { foreach ($SkypeUserRegistrarInvalid in $SkypeUsersRegistrarInvalid) { $myOU = $SkypeUserRegistrarInvalid.Identity | ForEach-Object{($_ -split "," | Select-Object -Skip 2)} $UserOU = $myOU -join ',' [array]$SkypeUserInvalidObjectAttribute = #() $SkypeUserInvalidObjectAttribute = Add-ArraySiteDefaultvsUserSettings ` -SiteCode $SkypeSiteDefault.'Site Code' ` -Identity $SkypeUserRegistrarInvalid.SamAccountName ` -OU $UserOU ` -SiteDefaultValue $SkypeSiteDefault.RegistrarPool ` -UserCurrentSettings $SkypeUserRegistrarInvalid.Registrarpool.FriendlyName ` -AlertType 'INVALID - REGISTRAR POOL' If ($SkypeUsersInvalidObjectAttribute.count -eq 0) { $SkypeUsersInvalidObjectAttribute = $SkypeUserInvalidObjectAttribute } else { $SkypeUsersInvalidObjectAttribute += $SkypeUserInvalidObjectAttribute } } } #Get-CsUser -ResultSize unlimited -ou $SkypeSiteDefault.OU | Where-Object {$_.Registrarpool -ne $SkypeSiteDefault.RegistrarPool} | Select SamAccountName, Registrarpool $SkypeSiteDefault.'Site Code' $SkypeSiteDefault.'Dial Plan' $SkypeSiteDefault.'Site Code' $SkypeSiteDefault.'Voice Policy' Write-Host '' Write-Host '' } } $SkypeUsersInvalidObjectAttribute | Export-CSV "C:\Scriptout\Test.csv"
Parrish - Thank you a lot for your answer: A Class is exactly the solution I needed. Class ObjectCompare { [String] $SiteCode [String] $Identity [String] $OU [String] $SiteDefault [String] $UserSetting [String] $IssueAlert } Function Add-ArraySiteDefaultvsUserSettings { Param ( $OU, $Identity, $SiteCode, $SiteDefaultValue, $UserCurrentSettings, $AlertType ) #SiteDefaultvsUserSettings [array]$DefaultvsUserSettings = #() $addObject = New-Object ObjectCompare # Add-DefaultsValidation $addObject.SiteCode = $SiteCode $addObject.Identity = $Identity $addObject.OU = $OU $addObject.SiteDefault = $SiteDefaultValue $addObject.UserSetting = $UserCurrentSettings $addObject.IssueAlert = $AlertType $DefaultvsUserSettings += $addObject #Write-Output $SiteDefaultvsUserSettings Return $DefaultvsUserSettings }
Powershell arrays into html tables
Ok so I have my first ever powershell script and it works exactly how I want it to. The output was just to a txt file and it was bland. Totally reworked it to give all results into a single array. mind you there maybe a better way to do this or I may have put too much code so suggestions welcomed.... my end goal is a html with just 2 rows.... Item and Result this is ran on a machine that will get registry settings, services startup types and local acct status. I just cant figure out how to do a table and cycle through the arrays. thanks for your help as it is greatly apprecaited!!!! # Static array of registry keys $RegKeys = #("DisableNotificationCenter","AutoConfiURL","HibernateEnabled","HideSCAHealth","NoDriveTypeAutoRun","TurnOffSidebar","EnableBaloonTips","UseDomainNameDevolution","DomainNameDevolutionlevel","*.one.ads","*","SearchOrderConfig","NoAutoRebootWithLoggedOnUsers","DisabledComponents","fAllowToGetHelp","fDenyTSConnections","EnableLUA","dontdisplaylastusername") #Static array of service names $Services = #("LanmanServer","MPSSVC","WinDefend","WSCSVC","TRKWKS","NAPAGENT","WUAUSERV") #Static array of users $Users = #("Admin","Guest") #Registry Keys $dnc = 'HKCU:\Software\Policies\Microsoft\Windows\Explorer' if (Test-Path $dnc) {$dnc = (Get-ItemProperty -Path "HKCU:\Software\Policies\Microsoft\Windows\Explorer").DisableNotificationCenter} else {$dnc = "Key not Found"} $acu = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings' if (Test-Path $acu) {$acu = (Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings").AutoConfigURL} else {$acu = "Key not Found"} $he = 'HKLM:\SYSTEM\CurrentControlSet\Control\Power' if (Test-Path $he) {$he = (Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Power").HibernateEnabled} else {$he = "Key not Found"} $hscah = 'HKLM:\SOFTWARE\MICROSOFT\WINDOWS\CurrentVersion\Policies\Explorer' if (Test-Path $hscah) {$hscah = (Get-ItemProperty -Path "HKLM:\SOFTWARE\MICROSOFT\WINDOWS\CurrentVersion\Policies\Explorer").HideSCAHealth} else {$hscah = "Key not Found"} $ndtar = 'HKLM:\SOFTWARE\MICROSOFT\WINDOWS\CurrentVersion\Policies\Explorer' if (Test-Path $ndtar) {$ndtar = (Get-ItemProperty -Path "HKLM:\SOFTWARE\MICROSOFT\WINDOWS\CurrentVersion\Policies\Explorer").NoDriveTypeAutoRun} else {$ndtar = "Key not Found"} $tos = 'HKLM:\SOFTWARE\MICROSOFT\WINDOWS\CurrentVersion\Policies\Windows\Sidebar' if (Test-Path $tos) {$tos = (Get-ItemProperty -Path "HKLM:\SOFTWARE\MICROSOFT\WINDOWS\CurrentVersion\Policies\Windows\Sidebar").TurnOffSidebar} else {$tos = "Key not Found"} $ebt = 'HKLM:\SOFTWARE\MICROSOFT\WINDOWS\CurrentVersion\Policies\Explorer\Advanced' if (Test-Path $ebt) {$ebt = (Get-ItemProperty -Path "HKLM:\SOFTWARE\MICROSOFT\WINDOWS\CurrentVersion\Policies\Explorer\Advanced").EnableBaloonTips} else {$ebt = "Key not Found"} $udnd = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient' if (Test-Path $udnd) {$udnd = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient").UseDomainNameDevolution} else {$udnd = "Key not Found"} $dndl = 'HKLM:\SYSTEM\CURRENTCONTROLSET\SERVICES\Dnscache\Parameters' if (Test-Path $dndl) {$dndl = (Get-ItemProperty -Path "HKLM:\SYSTEM\CURRENTCONTROLSET\SERVICES\Dnscache\Parameters").DomainNameDevolutionlevel} else {$dndl = "Key not Found"} $oads = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Domains\bms.com\*.one.ads' if (Test-Path $oads) {$oads = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Domains\bms.com\*.one.ads")."*"} else {$oads = "Key not Found"} $ads = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Domains\bms.com\*.one.ads' if (Test-Path $ads) {$ads = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Domains\bms.com\")."*"} else {$ads = "Key not Found"} $soc = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\DriverSearching' if (Test-Path $soc) {$soc = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\DriverSearching").SearchOrderConfig} else {$soc = "Key not Found"} $narwlou = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU' if (Test-Path $narwlou) {$narwlou = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU").NoAutoRebootWithLoggedOnUsers} else {$narwlou = "Key not Found"} $dc = 'HKLM:\SYSTEM\CurrentControlSet\services\TCPIP6\Parameters' if (Test-Path $dc) {$dc = (Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\services\TCPIP6\Parameters").DisabledComponents} else {$dc = "Key not Found"} $atgh = 'HKLM:\SYSTEM\CurrentControlSet\Control\Remote Assistance' if (Test-Path $atgh) {$atgh = (Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Remote Assistance").fAllowToGetHelp} else {$atgh = "Key not Found"} $dtsc = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services' if (Test-Path $dtsc) {$dtsc = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services").fDenyTSConnections} else {$dtsc = "Key not Found"} $elua = 'HKLM:\SOFTWARE\MICROSOFT\WINDOWS\CurrentVersion\Policies\System' if (Test-Path $elua) {$elua = (Get-ItemProperty -Path "HKLM:\SOFTWARE\MICROSOFT\WINDOWS\CurrentVersion\Policies\System").EnableLUA} else {$elua = "Key not Found"} $ddlun = 'HKLM:\SOFTWARE\MICROSOFT\WINDOWS\CurrentVersion\Policies\System' if (Test-Path $ddlun) {$ddlun = (Get-ItemProperty -Path "HKLM:\SOFTWARE\MICROSOFT\WINDOWS\CurrentVersion\Policies\System").dontdisplaylastusername} else {$ddlun = "Key not Found"} #Services $ls = (Get-WmiObject Win32_Service -filter "Name='LanmanServer'").StartMode $mpssvc = (Get-WmiObject Win32_Service -filter "Name='MPSSVC'").StartMode $wd = (Get-WmiObject Win32_Service -filter "Name='WinDefend'").StartMode $wscsvc = (Get-WmiObject Win32_Service -filter "Name='WSCSVC'").StartMode $trkwks = (Get-WmiObject Win32_Service -filter "Name='TRKWKS'").StartMode $napagent = (Get-WmiObject Win32_Service -filter "Name='NAPAGENT'").StartMode $wuauserv = (Get-WmiObject Win32_Service -filter "Name='WUAUSERV'").StartMode #Local Accounts $Adm = Get-WmiObject -Class Win32_UserAccount -Filter "LocalAccount='True' AND Name='Administrator'" $Admin = $Adm.Disabled $Gu = Get-WmiObject -Class Win32_UserAccount -Filter "LocalAccount='True' AND Name='Guest'" $Guest = $Gu.Disabled #Make individual arrays from each queried information $RegValues = #($dnc,$acu,$he,$hscah,$ndtar,$tos,$ebt,$udnd,$dndl,$oads,$ads,$soc,$narwlou,$dc,$atgh,$dtsc,$elua,$ddlun) $ServiceValues = #($ls,$mpssvc,$wd,$wscsvc,$trkwks,$napagent,$wuauserv) $UsersValues = #($Admin,$Guest) #Make array of all keys $RegAll = #($RegKeys[0], $RegValues[0],$RegKeys[1], $RegValues[1],$RegKeys[2], $RegValues[2],$RegKeys[3], $RegValues[3], $RegKeys[4], $RegValues[4], $RegKeys[5], $RegValues[5] $RegKeys[6], $RegValues[6], $RegKeys[7], $RegValues[7], $RegKeys[8], $RegValues[8], $RegKeys[9], $RegValues[9], $RegKeys[10], $RegValues[10] $RegKeys[11], $RegValues[11], $RegKeys[12], $RegValues[12], $RegKeys[13], $RegValues[13], $RegKeys[14], $RegValues[14], $RegKeys[15], $RegValues[15] $RegKeys[16], $RegValues[16], $RegKeys[17], $RegValues[17], $RegKeys[18], $RegValues[18], $Services[0], $ServiceValues[0], $Services[1], $ServiceValues[1] , $Services[2], $ServiceValues[2], $Services[3], $ServiceValues[3], $Services[4], $ServiceValues[4], $Services[5], $ServiceValues[5], $Services[6], $ServiceValues[6], $Users[0], $UsersValues[0], $Users[1], $UsersValues[1]) #output to html $RegAll # | Select #{label='Item';expression={$_}} | ConvertTo-HTML -Fragment -Property 'Item' |Out-File c:\Scripts.html
This is an example which I have used in a script. You can adpt it on your script. Ask when you need help. $YourArray = #() #Object one for the array $test1 = New-Object –TypeName PSObject $test1 | Add-Member –MemberType NoteProperty –Name Propert_1 –Value "Example1" $test1 | Add-Member –MemberType NoteProperty –Name Propert_2 –Value "Example2" $test1 | Add-Member -MemberType NoteProperty -Name Propert_3 -Value "Example3" #Object two for the array $test2 = New-Object –TypeName PSObject $test2 | Add-Member –MemberType NoteProperty –Name Propert_1 –Value "Example_2_1" $test2 | Add-Member –MemberType NoteProperty –Name Propert_2 –Value "Example_2_2" $test2 | Add-Member -MemberType NoteProperty -Name Propert_3 -Value "Example_2_3" $YourArray = $test1,$test2 $beginning = { #html code the format of the table #' <html> <head> <title>Report</title> <STYLE type="text/css"> BODY{background-color:#b0c4de;} TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;} TH{font-family:SegoeUI, sans-serif; font-size:15; border-width: 1px;padding: 3px;border-style: solid;border-color: black;background-color:#778899} TD{font-family:Consolas, sans-serif; font-size:12; border-width: 1px;padding: 3px;border-style: solid;border-color: black;} tr:nth-child(odd) { background-color:#d3d3d3;} tr:nth-child(even) { background-color:white;} </STYLE> </head> <h1>Stackoverflow example</h1> <table> <tr><th>Propert_1</th><th>Propert_2</th><th>Propert_3</th></tr> '# } #Mapping between Property and table $process = { $Propert_1 = $_.Propert_1 $Propert_2 = $_.Propert_2 $Propert_3 = $_.Propert_3 '<tr>' '<td bgcolor="#33CC33">{0}</td>' -f $Propert_1 '<td bgcolor="#FFFFFF">{0}</td>' -f $Propert_2 '<td bgcolor="#FFFFFF">{0}</td>' -f $Propert_3 '</tr>' } $end = { #' </table> </html> </body> '# } #Export the array in a html sheet $YourArray | ForEach-Object -Begin $beginning -Process $process -End $end | Out-File -FilePath "U:\Export_Report.html" -Encoding utf8
Powershell Group Array
I have a custom array $myresults = #() $w3svcID = $result.ReturnValue -replace "IISWebServer=", "" $w3svcID = $w3svcID -replace "'", "" $vdirName = $w3svcID = "/ROOT"; $vdirs = gwmi -namespace "root\MicrosoftIISv2" -class "IISWebVirtualDirSetting" foreach($vdir in $vdirs) { $vPool = $vdir.Apppoolid $vName = $vdir.Name $robj = New-Object System.Object $robj | Add-Member -type NoteProperty -name Path -value $vName $robj | Add-Member -type NoteProperty -name Pool -value $vPool $myresults += $robj } $myresults | group-object Pool I'd like to be able to Group the data in the form of a list where the group values (Path) is under the group-by values (Pool); like so: DefaultAppPool W3SVC\ W3VSC\1\ROOT\ MyAppPool W3SVC\1\ROOT\MyVirtual\
Give this a try: Get-WmiObject IISWebVirtualDirSetting -Namespace root\MicrosoftIISv2 | Group-Object AppPoolId | Foreach-Object{ $_.Name $_.Group | Foreach-Object { "`t$($_.Name)" } }
Unable to Return output from function
function Get-NaLUNbyMap { <# .DESCRIPTION Gets Lun Information for a particular initiatorgroup name & lunid .EXAMPLE Get-Inventory -computername server-r2 .EXAMPLE Import-Module NaLUNbyMap Get-NaLUNbyMap -igroup "IA" -lunid 1 #> [CmdletBinding()] param( [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)] [string[]]$igroup, [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)] [string[]]$lunid ) Process { $info = (Get-NaLun |Select #{Name="LUN";Expression={$_.path}},#{Name="Size";Expression={[math]::Round([decimal]$_.size/1gb,0)}},#{Name="OnlineStatus";Expression={$_.online}},#{Name="Group";Expression={([string]::Join(",",(Get-NaLun $_.path | get-nalunmap | select -ExpandProperty initiatorgroupname)))}},#{Name="LunID";Expression={Get-NaLun $_.path | get-nalunmap | select -ExpandProperty lunid}} | ?{$_.group -eq $igroup -and $_.lunid -eq $lunid}) return $info } } Hi Im unable to return output from this function, can some one please help me out!
That is some ugly code. :( Here is a cleaned up version. I think I found your problem. Your parameters are arrays, when they should be single values based on how you are using them. function Get-NaLUNbyMap { <# .DESCRIPTION Gets Lun Information for a particular initiatorgroup name & lunid .EXAMPLE Get-Inventory -computername server-r2 .EXAMPLE Import-Module NaLUNbyMap Get-NaLUNbyMap -igroup "IA" -lunid 1 #> [CmdletBinding()] param( [Parameter(Mandatory = $True, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] [string]$igroup , [Parameter(Mandatory = $True, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] [string]$lunid ) process { $Luns = foreach ($Lun in Get-NaLun) { $LunMap = Get-NaLunMap $_.Path New-Object PSObject -Property #{ "LUN"= $_.Path "Size" = [Math]::Round([Decimal]$_.Size / 1gb, 0) "OnlineStatus" = $_.Online "Group" = $LunMap | Select-Object -ExpandProperty InitiatorGroupName "LunId" = $LunMap | Select-Object -ExpandProperty LunId } } $Luns | Where-Object {$_.Group -eq $igroup -and $_.LunId -eq $lunid} } }