I obtained the BIOS data and saved it in HTML file but i don't want all the data to be in the file and i also need to format it so that it could suite my requirement.
Code:
$bios = get-wmiobject -class "Win32_BIOS" -namespace "root\CIMV2"
[string]$body = $bios | ConvertTo-Html -As List| Out-File c:/d/d/Test.htm
So based on the discussion in the comments, I think you are looking for something like this:
function GetCompInfoWork
{
param (
[string]$computername,[string]$logfile
)
$os = Get-WmiObject win32_operatingsystem -ComputerName $computername
$bios = Get-WmiObject win32_bios -ComputerName $computername
$disk = Get-WmiObject win32_logicalDisk -Filter "DeviceID= 'C:'" `
-computername $computername
$obj = New-Object -TypeName PSObject
$obj | Add-Member -MemberType NoteProperty `
-Name ComputerName -Value ($os.csname)
$obj | Add-Member -MemberType NoteProperty `
-Name Manufacturer -Value ($bios.manufacturer)
$obj | Add-Member -MemberType NoteProperty `
-Name SysDriveFree -Value ($disk.freespace / 1GB -as [int])
$obj | Add-Member -MemberType NoteProperty `
-Name SerialNumber -Value ($bios.serialnumber)
$obj | Add-Member -MemberType NoteProperty `
-Name Version -Value ($bios.version)
Write-Output $obj
}
function Get-CompInfo
{
param ([string[]]$computername,[string]$logfile )
BEGIN
{
$usedParamater = $False
if ($PSBoundParameters.ContainsKey('computername')) {
$usedParamater = $True
}
}
PROCESS {
if ($usedParamater)
{
foreach ($computer in $computername)
{
Getcompinfowork -computername $computer `
-logfile $logfile
}
}
else
{
Getcompinfowork -computername $_ `
-logfile $logfile
}
}
END {}
}
Get-CompInfo -computername localhost | ConvertTo-Html | Out-File C:\Output.html
Try this:
$freeSpace = (gwmi Win32_logicaldisk -Filter "DeviceID = 'C:'").FreeSpace
gwmi Win32_BIOS `
| select PSComputerName,Manufacturer,SerialNumber,Version,
#{n="AvailableSpace";e={[int]($freeSpace / 1MB)}} `
| ConvertTo-Html `
| Out-File "C:/d/d/Test.htm"
Related
I am trying to create a script which searches a list of computers/servers and identifies if a user profile exists for each member of an AD group called 'TestDisabledUsers'. Results are then piped to a CSV file with the format below.
ComputerName WMI_Connection Pingable Profile_Search
Computer1 Server IS Contactable TRUE User1 Exists ; User2 Exists ; User3 No Profile
Computer2 Server IS Contactable TRUE User1 No Profile ; User2 Exists ; User3 Exists
Computer3 Server IS Contactable TRUE User1 Exists ; User2 Exists ; User3 No Profile
Current script is not working at present as it only shows 1 user in the Profile_Search output :-(
Apologies if this is a simple solution, I'm not the best coder ;-) Any help very much appreciated.
So far I have the following powershell script :-
Clear-History
$ErrorActionPreference= 'silentlycontinue'
$outputFolderName = 'ProfileAudit ' + $(Get-Date -f dd-MM-yyyy)
$outputpath = "C:\temp\$outputFolderName"
If(!(test-path $outputpath))
{
New-Item -ItemType Directory -Force -Path $outputpath | out-null
}
$computers = Get-Content -path C:\Temp\svrs.txt
$report = #()
foreach ($computer in $computers) {
$Ping = Test-Connection -ComputerName $computer -Quiet -count 2
$wmi = gwmi win32_bios -ComputerName $computer
if ($wmi)
{
$WMIResult = 'Server IS Contactable'
$profiles = Get-ADGroupMember -Identity TestDisabledUsers | Foreach {$_.SamAccountName}
foreach ($profile in $profiles) {
$user = Get-CimInstance -ComputerName $computer -Class Win32_UserProfile | Where-Object { $_.LocalPath.split('\')[-1] -eq $profile }
if ($user)
{
$profileexists = ("$profile Exists") -join ' ; '
#$user | Remove-CimInstance
}
else {
$profileexists = ("$profile No Profile") -join ' ; '
}
}
$tempreport = New-Object -TypeName PSObject
$tempreport | Add-Member -MemberType NoteProperty -Name ComputerName -Value $Computer.ToUpper()
$tempreport | Add-Member -MemberType NoteProperty -Name WMI_Connection -Value $WMIResult
$tempreport | Add-Member -MemberType NoteProperty -Name Pingable -Value $Ping
$tempreport | Add-Member -MemberType NoteProperty -Name Profile_Search -Value $profileexists
$report += $tempreport
}
else
{
$WMIResult = 'Server NOT Contactable'
$tempreport = New-Object PSObject
$tempreport | Add-Member -MemberType NoteProperty -Name ComputerName -Value $Computer.ToUpper()
$tempreport | Add-Member -MemberType NoteProperty -Name WMI_Connection -Value $WMIResult
$tempreport | Add-Member -MemberType NoteProperty -Name Pingable -Value $Ping
$tempreport | Add-Member -MemberType NoteProperty -Name Profile_Search -Value $null
$report += $tempreport
}
}
$CSVFileName = 'ProfileAudit ' + $(Get-Date -f dd-MM-yyyy) + '.csv'
$report | Export-Csv $outputpath\$CSVFileName -NoTypeInformation
Try the below. The main issue is that you're overwriting $profileexists instead of appending to it in the profile loop.
Clear-History
$outputpath = "C:\temp\ProfileAudit $(Get-Date -f dd-MM-yyyy)"
If(!(test-path $outputpath))
{
New-Item -ItemType Directory -Force -Path $outputpath | out-null
}
$report = Get-Content -path C:\Temp\svrs.txt | % {
$ping = Test-Connection -ComputerName $_ -Quiet -count 2
$profileexists = $null
if(gwmi win32_bios -ComputerName $_)
{
$WMIResult = 'Server IS Contactable'
$profiles = Get-ADGroupMember -Identity TestDisabledUsers | select -ExpandProperty SamAccountName
foreach ($profile in $profiles) {
$user = Get-CimInstance -ComputerName $_ -Class Win32_UserProfile | Where-Object { $_.LocalPath.split('\')[-1] -eq $profile }
if ($user)
{
$profileexists += "$profile Exists;"
}
else {
$profileexists += "$profile No Profile;"
}
}
}
else
{
$WMIResult = 'Server NOT Contactable'
}
[pscustomobject]#{
ComputerName = $_.ToUpper()
WMI_Connection = $WMIResult
Pingable = $Ping
Profile_Search = $profileexists
}
}
$CSVFileName = 'ProfileAudit ' + $(Get-Date -f dd-MM-yyyy) + '.csv'
$report | Export-Csv $outputpath\$CSVFileName -NoTypeInformation
I am working on a PowerShell script for a customer to pull information from Servers before they are decommissioned. I have had to jump through a couple of hoops, as they have 2008 and even some 2003 servers, which don't always support the same Get-CimInstance queries, but for the most part it is working as expected. One section I have as yet been unable to fix however is pulling a list of all local groups and their members, like so:
$localGroups = Invoke-Command -ScriptBlock {
[ADSI]$S = "WinNT://$($env:computername)"
$S.children.Where({$_.class -eq 'group'}) |
Select #{Name="Name";Expression={$_.name.value}},
#{Name="Members";Expression={
[ADSI]$group = "$($_.Parent)/$($_.Name),group"
$members = $Group.psbase.Invoke("Members")
($members | ForEach-Object {$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)}) -join ";"
}
}
} -ComputerName $sPC | Select PSComputername,Name,Members
This works just fine on Server 2012 and above, but fails on 2008 and below. The specific error states:
Method invocation failed because [System.DirectoryServices.DirectoryEntries] doesn't contain a method named 'Where'
So the OS does not like the $S.Children.Where() call. Just curious if anyone knows of another way to format it for use with 2008 and earlier. I could probably go the old WMI call route, but that takes forever to finish.
I ended up finding a (fairly) quick way of doing it, works on all OS flavors:
function get-groups {
param ($strcomputer)
$groups = gwmi win32_group -ComputerName $strcomputer
return $groups
}
function Get-LocalGroupMembers {
param(
[parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
[Alias("Name")]
[string]$ComputerName,
[string]$GroupName = "Administrators"
)
begin {}
process {
$ComputerName = $ComputerName.Replace("`$", '')
$arr = #()
$wmi = Get-WmiObject -ComputerName $ComputerName -Query "SELECT * FROM Win32_GroupUser WHERE GroupComponent=`"Win32_Group.Domain='$ComputerName',Name='$GroupName'`""
if ($wmi -ne $null) {
foreach ($item in $wmi) {
$arr += ($item.PartComponent.Substring($item.PartComponent.IndexOf(',') + 1).Replace('Name=', '').Replace("`"", ''))
}
}
$hash = #{ComputerName=$ComputerName;Members=$arr}
return $hash
}
end{}
}
$sPC = "Server2008R2"
$a = 1
$adapterInfo = Get-CimInstance -query "Select * From
Win32_NetworkAdapterConfiguration Where IPenabled = 'TRUE'" -ComputerName $sPC
$serialNumber = Get-CimInstance -query "Select * From Win32_Bios" -ComputerName $sPC
$shares = Get-CimInstance -query "Select * From Win32_Share" -ComputerName $sPC
$localGroups = get-groups $sPC
$myObject = New-Object -TypeName PSObject
$myObject | Add-Member -MemberType NoteProperty -Name ComputerName -Value $adapterInfo.PSComputerName
$myObject | Add-Member -MemberType NoteProperty -Name Description -Value $adapterInfo.Description
$adapterInfo | ForEach-Object {
$_.IPAddress |
ForEach-Object {
$myObject | Add-Member -MemberType NoteProperty -Name "IPAddress$($a)" -Value $_
$a++
}
}
$myObject | Add-Member -MemberType NoteProperty -Name SerialNumber -Value $serialNumber.SerialNumber
foreach ($share in $shares) {
if ($share.Name -ne "C$" -and
$share.Name -ne "D$" -and
$share.Name -ne "ADMIN$" -and
$share.Name -ne "IPC$") {
$myObject | Add-Member -MemberType NoteProperty -Name "Share $($share.Name)" -Value $share.Path
}
}
foreach ($group in $localGroups) {
$members = ((Get-LocalGroupMembers -ComputerName $sPC -GroupName $group.Name).Members) -join "; "
if ($members.Length -ne 0) {
$myObject | Add-Member -MemberType NoteProperty -Name "$($group.Name) Members" -Value $members
}
}
$myObject | Export-Csv -Path "<Path to Folder>\$($sPC).csv" -NoTypeInformation
Hi all I want to get details in below format
Hostname Drive_0 Drive_1 Drive_2
Name C: 99.899227142334 d: 99.899227142334 e: 99.899227142334
I can get this detail using below script but this works on PowerShell 3.0
how can I change to execute on PowerShell 2.0
$result = #()
$obj = new-object PSobject
$server = hostname
$obj |Add-Member -MemberType NoteProperty -Name "Hostname" -Value $server -ErrorAction SilentlyContinue
$z = Get-WmiObject -Class win32_Logicaldisk -Filter 'DriveType=3' | Select-Object -Property DeviceID, #{LABEL='TotalSize';EXPRESSION={$_.Size/1GB}}
$z3 = $z.DeviceID
$z4 = $z.TotalSize
$i = 0
foreach($z3 in $z3){
$z1 = $z.DeviceID[$i]
$z2 = $z.TotalSize[$i]
$zx = "$z1" + ": $z2"
$obj | Add-Member -MemberType NoteProperty -Name "Drive_$i" -Value $zx -ErrorAction SilentlyContinue
$i++
}
$result+=$obj
$result | Export-Csv "$env:userprofile\Desktop\Result.csv" -NoTypeInformation
You can change your code to the below. It's a bit neater and sorts out your loops and limits so you don't need to manage them
$result = #()
$obj = new-object PSobject
$server = hostname
$obj |Add-Member -MemberType NoteProperty -Name "Hostname" -Value $server -ErrorAction SilentlyContinue
$z = Get-WmiObject -Class win32_Logicaldisk -Filter 'DriveType=3' | Select-Object -Property DeviceID, #{LABEL='TotalSize';EXPRESSION={$_.Size/1GB}}
$i = 0
$z | % {
$z1 = $_.DeviceID
$z2 = $_.TotalSize
$zx = "$z1" + ": $z2"
$obj | Add-Member -MemberType NoteProperty -Name "Drive_$i" -Value $zx
$i++
}
$result+=$obj
$result | Export-Csv "$env:userprofile\Desktop\Result.csv" -NoTypeInformation
I also removed the -ErrorAction off the Add-Member as you should try and handle anything that crops up yourself, but add it back if you feel the need to.
When I run the below code I get an error with Model Number in which the heading is not being displayed and one more thing is i am unable to get all the three of them in a sequence.
$arrComputers = get-Content -Path "C:\Desktop\Computers.txt"
$e=$arrComputers | ForEach-Object {Get-WMIObject -Class Win32_BIOS -ComputerName $_ } |Select PSComputerName, Version,Manufacturer,Status,BIOSVersion,SerialNumber |ConvertTo-Html -fragment
$e2=$arrComputers |ForEach-Object { get-wmiobject -class Win32_logicaldisk -Filter "DeviceID = 'C:'" -ComputerName $_ } | select freeSpace,size | ConvertTo-Html -fragment
$e3=$arrComputers |ForEach-Object { get-wmiobject -class "Win32_ComputerSystem" -ComputerName $_ } | select Model| ConvertTo-Html -fragment
ConvertTo-HTML -Body "$e $e2 $e3" -Title "List of Computers" | Out-File C:\Users\Desktop\gf.html
Its a lot easier to make all of the WMI calls into a single object. It is much easier to handle formatting. I think I got everything that you were wanting:
function GetCompInfoWork
{
param (
[string]$computername,[string]$logfile
)
$pc = Get-WmiObject Win32_ComputerSystem -ComputerName $computername
$bios = Get-WmiObject win32_bios -ComputerName $computername
$disk = Get-WmiObject win32_logicalDisk -Filter "DeviceID= 'C:'" `
-computername $computername
$obj = New-Object -TypeName PSObject
$obj | Add-Member -MemberType NoteProperty `
-Name PSCompName -Value ($bios.PSComputerName)
$obj | Add-Member -MemberType NoteProperty `
-Name Version -Value ($bios.version)
$obj | Add-Member -MemberType NoteProperty `
-Name Manufacturer -Value ($bios.manufacturer)
$obj | Add-Member -MemberType NoteProperty `
-Name Status -Value ($bois.status)
$obj | Add-Member -MemberType NoteProperty `
-Name SerialNumber -Value ($bios.serialnumber)
$obj | Add-Member -MemberType NoteProperty `
-Name DiskSize -Value ($disk.size / 1GB -as [int])
$obj | Add-Member -MemberType NoteProperty `
-Name SysDriveFree -Value ($disk.freespace / 1GB -as [int])
$obj | Add-Member -MemberType NoteProperty `
-Name ComputerName -Value ($pc.model)
Write-Output $obj
}
function Get-CompInfo
{
param ([string[]]$computername,[string]$logfile )
BEGIN
{
$usedParamater = $False
if ($PSBoundParameters.ContainsKey('computername')) {
$usedParamater = $True
}
}
PROCESS {
if ($usedParamater)
{
foreach ($computer in $computername)
{
Getcompinfowork -computername $computer `
-logfile $logfile
}
}
else
{
Getcompinfowork -computername $_ `
-logfile $logfile
}
}
END {}
}
Get-Content C:\Users\Kev\Desktop\computers.txt| Get-CompInfo | ConvertTo-Html | Out-File C:\Users\kev\Desktop\Output.html
im doing some testing with powershell to list hardware information of each computer in my domain. my script will get a list of computer from a text file that i created using powershell.
$arrComputers = get-Content -Path "C:\powershell\List.txt"
foreach ($strComputer in $arrComputers)
{
$colItemsOs = get-wmiobject -class "Win32_OperatingSystem" -namespace "root\CIMV2" `
-computername $strComputer
foreach ($objItem in $colItemsOs)
{
Write-host "Computer Name: " $strComputer
Write-host "OsName: " $objItem.Name
Write-host "Version: " $objItem.Version
}
$colItemsCompsys = get-wmiobject -class "Win32_ComputerSystem" -namespace "root\CIMV2" `
-computername $strComputer
foreach ($objItem in $colItemsCompsys)
{
Write-host "Memory: " $objItem.TotalPhysicalMemory
Write-host "Manufacturer: " $objItem.Manufacturer
Write-host "Model: " $objItem.Model
Write-host "Domain: " $objItem.Domain
}
$colItemsSysEnc = get-wmiobject -class "Win32_SystemEnclosure" -namespace "root\CIMV2" `
-computername $strComputer
foreach ($objItem in $colItemsSysEnc)
{
Write-host "SerialNumber: " $objItem.SerialNumber
}
$colItemsProcessor = get-wmiobject -class "Win32_Processor" -namespace "root\CIMV2" `
-computername $strComputer
foreach ($objItem in $colItemsProcessor)
{
Write-host "Processor: " $objItem.Name
}
$colItemsIP = get-wmiobject -class "Win32_NetworkAdapterConfiguration " -namespace "root\CIMV2" `
-computername $strComputer -Filter "IpEnabled = TRUE"
foreach ($objItem in $colItemsIP)
{
Write-host "IPAddress: " $objItem.IpAddress
}
Write-host | Out-File c:\powershell\reportbeta.csv
}
however, i am unable to do so. how do i produce the result in csv file which will be able to be uploaded to my database using sqlcmd later on.
what am i missing out?
thank you
ive managed to display output in text file. however, only 1 record is displayed.
$arrComputers = get-Content -Path "C:\powershell\List.txt"
foreach ($strComputer in $arrComputers)
{
$colItemsOs = get-wmiobject -class "Win32_OperatingSystem" -namespace "root\CIMV2" `
-computername $strComputer
foreach ($objItem in $colItemsOs)
{
$strComputer
$Name =$objItem.Name
$Version = $objItem.Version
}
$colItemsCompsys = get-wmiobject -class "Win32_ComputerSystem" -namespace "root\CIMV2" `
-computername $strComputer
foreach ($objItem in $colItemsCompsys)
{
$TotalMemory = $objItem.TotalPhysicalMemory
$Manufacturer = $objItem.Manufacturer
$Model = $objItem.Model
$Domain = $objItem.Domain
}
$colItemsSysEnc = get-wmiobject -class "Win32_SystemEnclosure" -namespace "root\CIMV2" `
-computername $strComputer
foreach ($objItem in $colItemsSysEnc)
{
$SerialNUmber = $objItem.SerialNumber
}
$colItemsProcessor = get-wmiobject -class "Win32_Processor" -namespace "root\CIMV2" `
-computername $strComputer
foreach ($objItem in $colItemsProcessor)
{
$Processor = $objItem.Name
}
$colItemsIP = get-wmiobject -class "Win32_NetworkAdapterConfiguration " -namespace "root\CIMV2" `
-computername $strComputer -Filter "IpEnabled = TRUE"
foreach ($objItem in $colItemsIP)
{
$IPV4 = $objItem.IpAddress
}
$OutputObj = New-Object -Type PSObject
$OutputObj | Add-Member -MemberType NoteProperty -Name ComputerName -Value $strComputer.ToUpper()
$OutputObj | Add-Member -MemberType NoteProperty -Name Name -Value $Name
$OutputObj | Add-Member -MemberType NoteProperty -Name Version -Value $Version
$OutputObj | Add-Member -MemberType NoteProperty -Name TotalPhysicalMemory -Value $TotalMemory
$OutputObj | Add-Member -MemberType NoteProperty -Name Manufacturer -Value $Manufacturer
$OutputObj | Add-Member -MemberType NoteProperty -Name Model -Value $Model
$OutputObj | Add-Member -MemberType NoteProperty -Name Processor -Value $ProcessorSpeed
$OutputObj | Add-Member -MemberType NoteProperty -Name SerialNumber -Value $SerialNo
$OutputObj | Add-Member -MemberType NoteProperty -Name Domain -Value $Domain
$OutputObj | Add-Member -MemberType NoteProperty -Name IPAddress -Value $IPV4
$OutputObj | Export-CSV -NoTypeInformation "c:\powershell\report.txt"
}
im out of ideas now. should i make it into array like?
please advise.
Thank you
The problem is that you are exporting to csv within the loop, so the last item will be the only one showing. Try something like this.
Before the loop:
# Create empty array
$report = #()
At the end of the loop, in place of where you are currently exporting to CSV:
#Add item to report
$report += $OutputObj
Finally, after the end of the loop:
$report | Export-CSV -NoTypeInformation "c:\powershell\report.txt"
I suggest you assign the foreach result to a variable then pipe it to Export-Csv. It should perform faster and is much efficient than recreating, and updating, an array in each loop iteration.
$result = foreach($strComputer in $arrComputers)...
$result | Export-CSV ...
If you used the Foreach-Object' cmdlet to loop over computers you could skip the whole assignment or array creation, processing one object at a time (streamlined) and pipe directly toExport-CSV`:
Get-Content -Path C:\powershell\List.txt | Foreach-Object{
...
} | Export-Csv ...