Powershell Compare Objects from multiple sources - powershell

I'm trying to build out a script to compare multiple CSV files and identify the delta in one master file. I think I'm close to having what I need but, I'm running into an issue when trying to set the value for the property on the master object.
I'm pulling in one CSV file (Sample) that has Computer Name, Location, IP, Active Directory, SCCM that I'm comparing to outputs from Active Directory (Compare) with the same information. I just want to update the first file with either a yes or no that the system is in Active Directory in the column called AD.
Here is the code that I have and need some guidance on fixing it:
$Sample = Import-Csv C:\Scripts\Sample_test_v1.csv
$Compare = Import-Csv C:\Scripts\Sample_AD_v1.csv
$Final = #()
foreach ($Samples in $Sample)
{
$Final = New-Object System.Object
$Final | Add-Member -type NoteProperty -name "Computer Name" -value $Samples.ComputerName
$Final | Add-Member -type NoteProperty -name "IP Address" -value $Samples.IP
$Final | Add-Member -type NoteProperty -name "Location" -value $Samples.Location
If ($Samples.ComputerName -contains $compare)
{$Final | Add-Member -type NoteProperty -name "Active Directory" -value "Yes"}
Else
{$Final | Add-Member -type NoteProperty -name "Active Directory" -value "Yes"}
}

With contains, you want the collection to come first. (Also changes Samples/Sample for clarity)
$Samples = Import-Csv C:\Scripts\Sample_test_v1.csv
$Compare = Import-Csv C:\Scripts\Sample_AD_v1.csv
$NewSamples = foreach ($Sample in $Samples) {
If ($Compare.Computername -contains $Sample.ComputerName) {
$Sample.AD = "Yes"
} Else {
$Sample.AD = "No"
}
$Sample
}
$NewSamples | Export-Csv C:\Scripts\Sample_test_v1.new.csv -notype

I figured out my problem with the below code which works now:
$Final = #()
$Samples = Import-Csv C:\Scripts\Sample_test_v1.csv
$Compare = Import-Csv C:\Scripts\Sample_AD_v1.csv
foreach ($Sample in $Samples)
{
$Sys = New-Object System.Object
$Sys | Add-Member -type NoteProperty -name "Computer Name" -value $Sample.ComputerName
$Sys | Add-Member -type NoteProperty -name "IP Address" -value $Sample.IP
$Sys | Add-Member -type NoteProperty -name "Location" -value $Sample.Location
If ($compare.computername -contains $Sample.ComputerName )
{$Sys | Add-Member -type NoteProperty -name "Active Directory" -value "Yes"}
Else
{ $Sys | Add-Member -type NoteProperty -name "Active Directory" -value "No" }
$Final += $Sys
}

Related

How to find email adress of AzureAD user with ps1 script

here is the script i use to export the data from AzureAD to csv.
Connect-AzureAD
Connect-MsolService
$date = Get-Date -UFormat "%d%m%Y"
$dateInfo = Get-Date
$Results = #()
$Roles = Get-AzureADDirectoryRole
foreach ($Role in $Roles) {
$MemberRole = Get-AzureADDirectoryRoleMember -ObjectId $Role.ObjectId
foreach ($Membre in $MemberRole ) {
$InfosUsers = Get-MsolUser -ObjectId $Membre.ObjectId
$List = New-Object System.Object
$List | Add-Member -type NoteProperty -name Compte -Value $Membre.DisplayName
$List | Add-Member -type NoteProperty -name Active -Value $Membre.AccountEnabled
$List | Add-Member -type NoteProperty -name Role -Value $Role.DisplayName
$List | Add-Member -type NoteProperty -name NumeroTel -Value $InfosUsers.StrongAuthenticationUserDetails.PhoneNumber
$Results += $List
}
}
$Results | Export-Csv path/to/the/file/ -NoTypeInformation
Disconnect-AzureAD
The things is that i would like to get mail adresse from user and i dont know how to do ?
Happy to see you already got your answer, here is one alternative way you can approach to get the email address of Azure AD user.
I did Few changes in your code (ie I have removed Connect-MsolService and replace Get-MsolUser with Get-AzADUser.) and I am able to perform the operation you are trying to do .
Connect-AzureAD
$date = Get-Date -UFormat "%d%m%Y"
$dateInfo = Get-Date
$Results = #()
$Roles = Get-AzureADDirectoryRole
foreach ($Role in $Roles) {
$MemberRole = Get-AzureADDirectoryRoleMember -ObjectId $Role.ObjectId
foreach ($Membre in $MemberRole ) {
$InfosUsers = Get-AzADUser -ObjectId $Membre.ObjectId
$List = New-Object System.Object
$List | Add-Member -type NoteProperty -name Compte -Value $Membre.DisplayName
$List | Add-Member -type NoteProperty -name Active -Value $Membre.AccountEnabled
$List | Add-Member -type NoteProperty -name Role -Value $Role.DisplayName
$List | Add-Member -type NoteProperty -name NumeroTel -Value $InfosUsers.StrongAuthenticationUserDetails.PhoneNumber
$List | Add-Member -type NoteProperty -name Email -Value $Membre.Mail
$List | Add-Member -type NoteProperty -name UPName -Value $Membre.UserPrincipalName
$Results += $List
}
}
$Results | Export-Csv /RahulS -NoTypeInformation
Output---

Issue with foreach loop (Combining Commands)

The script below works out great for identifying licensing for each individual host across multiple vCenters. What I am trying to include is the tag for each host as well. When I run the command individually it works fine, however when I run it as part of the code it is not functioning correctly. I highlighted the section if anyone can please take a look thanks. The line of code with the issue is commented out within the script below.
I attempted pushing this into a variable outside and insideof the foreach loop but I am receiving either 0 output, or the same output across each object.
Below is the actual command I put inside the foreach loop which is not functional.
(Get-VMhost | where{$_.Category -like "*Host*"})
$sw = [Diagnostics.Stopwatch]::StartNew()
# Declare our list of vCenters
[array]$vclistall = "vcenter01"
# Ensure were not connected to any vcenters
if ($DefaultVIServer.Count -gt 0) {
Disconnect-VIServer * -Confirm:$false -ErrorAction SilentlyContinue -WarningAction SilentlyContinue -Force:$true > $null
}
[array]$report = $null
foreach ($ScriptVCInstance in $vclistall) {
$connection = Connect-VIServer $ScriptVCInstance -ErrorAction SilentlyContinue
if ($connection) {
Write-Host "Collecting License Assets on vCenter $($ScriptVCInstance)"
# Get the license manager assets
$LicenseManager = Get-view LicenseManager
$LicenseAssignmentManager = Get-View $LicenseManager.LicenseAssignmentManager
$licenses = $LicenseAssignmentManager.GetType().GetMethod("QueryAssignedLicenses").Invoke($LicenseAssignmentManager, #($null))
#Format the asset into an object
foreach ($license in $Licenses) {
$object = New-Object -TypeName PSObject
$object | Add-Member -MemberType NoteProperty -Name "vCenter" -Value $($connection.name)
$object | Add-Member -MemberType NoteProperty -Name "Entity" -Value $($license.EntityDisplayName)
$object | Add-Member -MemberType NoteProperty -Name "Display Name" -Value $($license.Properties | where{$_.Key -eq 'ProductName'} | select -ExpandProperty Value)
$object | Add-Member -MemberType NoteProperty -Name "Product Version" -Calue $($License.Properties | where{$_.Key -eq 'FileVersion'} | select -ExpandProperty Value)
$object | Add-Member -MemberType NoteProperty -Name "License" -Value $($license.AssignedLicense.LicenseKey)
$object | Add-Member -MemberType NoteProperty -Name "License Name" -Value $($license.AssignedLicense.Name)
$object | Add-Member -MemberType NoteProperty -Name "Cost Unit" -Value $($license.Properties | where{$_.Key -eq 'CostUnit'} | select -ExpandProperty Value)
$object | Add-Member -MemberType NoteProperty -Name "Used License" -Value $($license.Properties | where{$_.Key -eq 'EntityCost'} | select -ExpandProperty Value)
$object | Add-Member -MemberType NoteProperty -Name "Total Licenses" -Value $($license.AssignedLicense.Total)
# Issue--> $object | Add-Member -MemberType NoteProperty -Name "Tag" -Value $(Get-VMhost | where{$_.Category -like "*Host*"})
$report += $object
if ($DefaultVIServer.Count -gt 0) {
Disconnect-VIServer * -Confirm:$false -ErrorAction SilentlyContinue -WarningAction SilentlyContinue -Force:$true > $null
}
} #end foreach $license
} else { # Else for if $connection
Write-warning "Not connected to vCenter $($ScriptVCInstance)"
} # endif $connection
} # End foreach $ScriptVCInstance
# write-out as a CSV file
Write-host "Exporting CSV $($env:USERPROFILE)\Licensed-Assets.csv"
$report | Sort-object "vCenter","License","Entity" | Export-csv "$($env:USERPROFILE)\Licensed-Assets.csv" -NoTypeInformation -UseCulture
$sw.Stop()
$sw.Elapsed

powershell script to return all forwarding rules in org

I need to pull all forwarding rules for an exchange online environment, and output them to a csv. this sounds simple, but I have an additional caveat. there are 23,000 mailboxes in the org.
I was able to write the script I needed, it outputted the data, but it timed out.
then I was able to break out only certain mailboxes that were critical (11,000) but I was still timing out in powershell.
so finally, I found an article that detailed breaking up a script into blocks of 1,000, and running numerous sessions. and runs! it runs without timing out.
but it doesn't output to the csv anymore.
since my script has gone through several iterations, I'm pretty sure that my problem is the way I'm storing, or outputting the array, but for all my staring at this, I cant figure it out. short of asking the doc for a prescription of Adderall, I figured id ask here. below is the offending script.
the aliaslist.csv that it mentions is just a csv with a list of aliases for 11,000 mailboxes. if you would like to run your own tests, you can adjust $pagesize down and paste a few mailboxes into a csv called aliaslist, stored in c:\temp
Function New-O365ExchangeSession()
{
param(
[parameter(mandatory=$true)]
$365master)
#close any old remote session
Get-PSSession | Remove-PSSession -Confirm:$false
#start a new office 365 remote session
$365session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "https://outlook.office365.com/powershell-liveid/" -Credential $365master -Authentication Basic -AllowRedirection
$office365 = Import-PSSession $365session
}
#set input variables
$path = "C:\temp"
$InputFile = aliaslist.csv"
$UserEmail = "admin#domain.com"
#set variables for csv usage
$Offset = 0;
$PageSize = 1000;
$MbxMax = (Import-Csv "$path/$InputFile").count
#Loop in the list and retrieve the device’s information
$file = “c:\temp\office365-$((get-date).tostring(“yyyy-MM-dd”)).csv”
$365master = get-credential $UserEmail
New-O365ExchangeSession $365master
# call the office365 remote connection function
do{
$mbxlist=#(import-csv "$path/$InputFile"|select-object -skip $Offset -First $PageSize)
"Process entry $($Offset) to $($Offset+$PageSize)"
#end csv input count reference
ForEach($mbx in $MbxList)
{
#Write to Host
"start Processing $($mbx.alias)"
#end Write to host,
#Check rules
$rules = Get-InboxRule -mailbox $_.alias | ? {$_.RedirectTo -ne $null -or $_.ForwardTo -ne $null -or $_.ForwardAsAttachmentTo -ne $null}
If ($rules -ne $null)
{
$rules | % {
#check for forwardAsAttachments
If ($_.ForwardAsAttachmentTo -ne $null)
{
$obj = New-Object system.object
$obj | Add-Member -name "NetID" -Value $_.alias -MemberType NoteProperty
$obj | Add-Member -name "ForwardType" -Value "Forward As Attachment Rule" -MemberType NoteProperty
$obj | Add-Member -name "ForwardAddress" -Value $_.forwardAsAttachmentTo -MemberType NoteProperty
$obj | Add-Member -name "Enabled" -Value $_.Enabled -MemberType NoteProperty
$obj | Add-Member -name "Description" -Value $f -MemberType NoteProperty
If (Test-Path $file)
{
$mbx.alias + ”,” + ($obj | ConvertTo-Csv)[2] | Out-File $file –Append
}
Else
{
$obj | Export-Csv $file -Encoding ASCII -notypeinformation
}
}
$obj = $null
#check for redirects
If ($_.redirectto -ne $null)
{
$obj = New-Object system.object
$obj | Add-Member -name "NetID" -Value $_.alias -MemberType NoteProperty
$obj | Add-Member -name "ForwardType" -Value "Redirct Rule" -MemberType NoteProperty
$obj | Add-Member -name "ForwardAddress" -Value $_.redirectto -MemberType NoteProperty
$obj | Add-Member -name "Enabled" -Value $_.Enabled -MemberType NoteProperty
$obj | Add-Member -name "Description" -Value $c -MemberType NoteProperty
If (Test-Path $file)
{
$mbx.alias + ”,” + ($obj | ConvertTo-Csv)[2] | Out-File $file –Append
}
Else
{
$obj | Export-Csv $file -Encoding ASCII -notypeinformation
}
}
$obj = $null
#check for forwards
If ($_.ForwardTo -ne $null)
{
$obj = New-Object system.object
$obj | Add-Member -name "NetID" -Value $_.alias -MemberType NoteProperty
$obj | Add-Member -name "ForwardType" -Value "Forward Rule" -MemberType NoteProperty
$obj | Add-Member -name "ForwardAddress" -Value $_.forwardto -MemberType NoteProperty
$obj | Add-Member -name "Enabled" -Value $_.Enabled -MemberType NoteProperty
$obj | Add-Member -name "Description" -Value $f -MemberType NoteProperty
If (Test-Path $file)
{
($obj | ConvertTo-Csv)[2] | Out-File $file –Append
}
Else
{
$obj | Export-Csv $file -Encoding ASCII -notypeinformation
}
}
$obj = $null
}
}
}
#increment the start point for the next chunk
$Offset+=$PageSize
#Call the office365 remote session function to close the current one and open a new session
New-O365ExchangeSession $365master
} while($Offset -lt $MbxMax)

Copy entire list using Powershell CSOM sharepoint

I need to export an entire list as a .csv file. I actually have this code which works great but I need to write each column I want to export:
$listTitle = "Example"
$list = $ctx.get_web().get_lists().getByTitle($listTitle);
$query = New-Object Microsoft.SharePoint.Client.CamlQuery;
$query.ViewXml = "<View><Query><Where><Geq><FieldRef Name='ID' /><Value Type='Counter'>1</Value></Geq></Where></Query></View>"
$listItems = $list.GetItems($query);
$ctx.Load($listItems);
$ctx.ExecuteQuery();
$tableau =#();
foreach ($listItem in $listItems)
{
$result = new-object psobject
$result | Add-Member -MemberType noteproperty -Name Title -value $listItem['Title'];
$result | Add-Member -MemberType noteproperty -Name Description -value $listItem['Description'];
$result | Add-Member -MemberType noteproperty -Name Age -value $listItem['Age'];
$result | Add-Member -MemberType noteproperty -Name Sexe -value $listItem['Sexe'];
$tableau += $result;
}
$CsvName2 = "Export_"+$ListTitle.replace(' ','_')+".csv"
$tableau | export-csv $CsvName2 -notype;
The part I want to improve is the foreach loop:
foreach ($listItem in $listItems)
{
$result = new-object psobject
$result | Add-Member -MemberType noteproperty -Name Title -value $listItem['Title'];
$result | Add-Member -MemberType noteproperty -Name Description -value $listItem['Description'];
$result | Add-Member -MemberType noteproperty -Name Age -value $listItem['Age'];
$result | Add-Member -MemberType noteproperty -Name Sexe -value $listItem['Sexe'];
$tableau += $result;
}
I want the script collects all columns but I don't know how to do it...
I got this advice: Replace my loop with:
foreach ($listItem in $listItems)
{
$result = new-object psobject
foreach ($field in $listItem.Fields)
{
if ($field.Hidden -eq $false)
{
$result | Add-Member -MemberType noteproperty -Name $field.Title -value $listItem[$field.InternalName];
}
}
$tableau += $result;
}
But all I got is a blank file. I don't really understand structure of list/filed items.
Thanks for your help.

PowerShell to fetch installed programs

I will be hosting a file on a remote server (read-only) and asking people to run the file on their machines to gather installed program information. I want the file to be saved to their Desktop in their user space, so that I can then have them send it to us.
I have the script, but I'm not managing to obtain information from both "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", and "Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" in the same output file. I'm obviously missing something inherently obvious, as PowerShell is clearly able to do this, and I'm asking that someone please save me from my PEBKAC issue!
Thank you in advance, appreciated!
Here is my code;
$computers = "$env:computername"
$array = #()
foreach($pc in $computers){
$computername=$pc
$UninstallKey="SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"
$UninstallKey="Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
$reg=[microsoft.win32.registrykey]::OpenRemoteBaseKey('LocalMachine',$computername)
$regkey=$reg.OpenSubKey($UninstallKey)
$subkeys=$regkey.GetSubKeyNames()
Write-Host "$computername"
foreach($key in $subkeys){
$thisKey=$UninstallKey+"\\"+$key
$thisSubKey=$reg.OpenSubKey($thisKey)
$obj = New-Object PSObject
$obj | Add-Member -MemberType NoteProperty -Name "ComputerName" -Value $computername
$obj | Add-Member -MemberType NoteProperty -Name "DisplayName" -Value $($thisSubKey.GetValue("DisplayName"))
$obj | Add-Member -MemberType NoteProperty -Name "DisplayVersion" -Value $($thisSubKey.GetValue("DisplayVersion"))
$obj | Add-Member -MemberType NoteProperty -Name "InstallLocation" -Value $($thisSubKey.GetValue("InstallLocation"))
$obj | Add-Member -MemberType NoteProperty -Name "Publisher" -Value $($thisSubKey.GetValue("Publisher"))
$array += $obj
}
}
$array | Where-Object { $_.DisplayName } | select ComputerName, DisplayName, DisplayVersion, Publisher | export-csv C:\Users\$env:username\Desktop\Installed_Apps.csv
Right now the following two lines set the same variable:
$UninstallKey="SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"
$UninstallKey="Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
Use this:
$UninstallKey = #(
'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
'SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
)
Then wrap the real logic in:
$UninstallKey | ForEach-Object {
$regkey=$reg.OpenSubKey($_)
# the rest of your logic here
}