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
Related
I am doing an export of mailboxes from Office 365.
Some mailboxes the have the same primarysmtpaddress are active and also Inactive.
I enter code here have the following code:
$MBX = import-csv "c:\retention\LegalHold\test.csv"
$MBX | Add-Member -MemberType NoteProperty -Name Retention -Value NoPolicy
$MBX | Add-Member -MemberType NoteProperty -Name NoMailbox -Value $False
$MBX | Add-Member -MemberType NoteProperty -Name IsInactiveMailbox -Value $null
$MBX | Add-Member -MemberType NoteProperty -Name PrimarySmtpAddress -Value $null
$count=0
$fullcount = ($mbx | measure-object).count
foreach ($M in $MBX){
$policy = $null
$count++
$search = $m.custodian.tostring()
Write-progress -activity "Checking Mailbox $count out of $fullcount --- $search " -percentcomplete (($count / $fullcount)*100) -status "Processing"
Try{
$ErrorActionPreference = 'Stop'
$Policy = Invoke-Command -scriptblock {Get-EXOMailbox $m.custodian -IncludeInactiveMailbox -properties primarysmtpaddress,inplaceholds,isinactivemailbox,LitigationHoldEnabled,LitigationHoldDuration,Office}
#$Policy = Invoke-Command -scriptblock {Get-Mailbox $m.name -IncludeInactiveMailbox}
#$m.MBXFound = $True
$m.IsInactiveMailbox = $Policy.IsInactiveMailbox -join ','
$m.PrimarySmtpAddress = $Policy.PrimarySmtpAddress -join ','
}Catch{$m.NoMailbox = "$True"}
}
$MBX | export-csv C:\retention\legalhold\test_check.csv -NoTypeInformation
Instead of outputting to the CSV like this:
I'd like to have the mailboxes with an active and inactive mailbox on separate lines like this:
You would need to loop through the results of $Policy instead of just using -join.
$MBX = import-csv "c:\retention\LegalHold\test.csv"
$MBX | Add-Member -MemberType NoteProperty -Name Retention -Value NoPolicy
$MBX | Add-Member -MemberType NoteProperty -Name NoMailbox -Value $False
$MBX | Add-Member -MemberType NoteProperty -Name IsInactiveMailbox -Value $null
$MBX | Add-Member -MemberType NoteProperty -Name PrimarySmtpAddress -Value $null
$count=0
$fullcount = ($mbx | measure-object).count
$Output = foreach ($M in $MBX){
$policy = $null
$count++
$search = $m.custodian.tostring()
Write-progress -activity "Checking Mailbox $count out of $fullcount --- $search " -percentcomplete (($count / $fullcount)*100) -status "Processing"
Try{
$ErrorActionPreference = 'Stop'
$Policy = Invoke-Command -scriptblock {Get-EXOMailbox $m.custodian -IncludeInactiveMailbox -properties primarysmtpaddress,inplaceholds,isinactivemailbox,LitigationHoldEnabled,LitigationHoldDuration,Office}
#$Policy = Invoke-Command -scriptblock {Get-Mailbox $m.name -IncludeInactiveMailbox}
#$m.MBXFound = $True
$Policy | ForEach-Object {
$m.IsInactiveMailbox = $_.IsInactiveMailbox
$m.PrimarySmtpAddress = $_.PrimarySmtpAddress
$m
}
}Catch{$m.NoMailbox = "$True";$m}
}
$Output | export-csv C:\retention\legalhold\test_check.csv -NoTypeInformation
So a friend and i wrote a script so we could get some info about the share on our file server but i keep getting an error about the shares, I am a Domain Admin so i dont think the problem is with my permissions.
Here is the script:
$MyPath = "C:\File Share Info\Shares"
$shares = gwmi -Class win32_share -ComputerName $computer #| select -ExpandProperty Name
$AllObjects = #()
foreach ($share in $shares) {
$acl = $null
$ShareName = $share.Name
$ShareCaption = $Share.Caption
if ($ShareName -notlike "*$*"){
$objShareSec = Get-WMIObject -Class Win32_LogicalShareSecuritySetting -Filter "name='$ShareName'"
#-ComputerName $computer
try {
$SD = $objShareSec.GetSecurityDescriptor().Descriptor
foreach($ace in $SD.DACL){
$UserName = $ace.Trustee.Name
If ($ace.Trustee.Domain -ne $Null) {$UserName = "$($ace.Trustee.Domain)\$UserName"}
If ($ace.Trustee.Name -eq $Null) {$UserName = $ace.Trustee.SIDString }
[Array]$ACL = New-Object Security.AccessControl.FileSystemAccessRule($UserName, $ace.AccessMask, $ace.AceType)
$Identity = $ACL[0].IdentityReference.Value
$myObject = New-Object System.Object
$myObject | Add-Member -type NoteProperty -name ShareAccessType -Value $ACL[0].AccessControlType
$myObject | Add-Member -type NoteProperty -name Identity -Value $Identity
$myObject | Add-Member -type NoteProperty -name ShareRights -Value $ACL[0].FileSystemRights
$myObject | Add-Member -type NoteProperty -name SharePath -Value $Share.Path
$myObject | Add-Member -type NoteProperty -name ShareName -Value $Share.Name
$myObject | select ShareName, Identity, ShareRights, SharePath, ShareAccessType | Export-Csv "$MyPath\permissions.csv" -Append -Encoding Unicode #-NoTypeInformation -Delimiter "`t"
}
}
catch
{ Write-Host "Unable to obtain permissions for `"$ShareName`""; $share.Name | Out-File "$MyPath\Failed.txt" -Append}
}
}
Below code was in powershell that code is successfully executed but i want that output in special 'popup window'
$ComputerName = $s = $(Get-WmiObject Win32_Computersystem).name
foreach ($Computer in $ComputerName) {
if(Test-Connection -ComputerName $Computer -Count 1 -ea 0) {
$Networks = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $Computer | ? {$_.IPEnabled}
foreach ($Network in $Networks) {
$IPAddress = $Network.IpAddress[0]
$SubnetMask = $Network.IPSubnet[0]
$DefaultGateway = $Network.DefaultIPGateway
$DNSServers = $Network.DNSServerSearchOrder
$OutputObj = New-Object -Type PSObject
$OutputObj | Add-Member -MemberType NoteProperty -Name IPAddress -Value $IPAddress
$OutputObj | Add-Member -MemberType NoteProperty -Name SubnetMask -Value $SubnetMask
$OutputObj | Add-Member -MemberType NoteProperty -Name Gateway -Value $DefaultGateway
$OutputObj | Add-Member -MemberType NoteProperty -Name DNSServers -Value $DNSServers
}
}
}
The most familiar data displayer in powershell is using the Out-gridview method:
You can do this if you want to go easy:
$ComputerName = $s = $(Get-WmiObject Win32_Computersystem).name
$Pop_Window = foreach ($Computer in $ComputerName) {
if(Test-Connection -ComputerName $Computer -Count 1 -ea 0) {
$Networks = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $Computer | ? {$_.IPEnabled}
foreach ($Network in $Networks) {
$IPAddress = $Network.IpAddress[0]
$SubnetMask = $Network.IPSubnet[0]
$DefaultGateway = $Network.DefaultIPGateway
$DNSServers = $Network.DNSServerSearchOrder
$OutputObj | Add-Member -MemberType NoteProperty -Name IPAddress -Value $IPAddress
$OutputObj | Add-Member -MemberType NoteProperty -Name SubnetMask -Value $SubnetMask
$OutputObj | Add-Member -MemberType NoteProperty -Name Gateway -Value $DefaultGateway
$OutputObj | Add-Member -MemberType NoteProperty -Name DNSServers -Value $DNSServers
#output the object:
$OutputObj
}
}
}
$Pop_Window | Out-GridView
If you want to design it on your way, This would be a difficult and a messy task to do in powershell, since you always will have to call System.Windows.Forms class and its sub classes like Labels,Buttons,Texts and more.
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