What's the fastest way to merge two arrays using a common property?
Users | Select *
Username : Joe.Doe
Office : Chicago
Email :
Username : Mike.Smith
Office : New York
Email :
...
UserEmails | Select *
AccountEmail : Mike.Smith
EmailAddress : mike-smith#example.com
AccountEmail : Joe.Doe
EmailAddress : jsmith12#example.com
...
The merge should result in:
UsersCompleteList | Select *
Username : Joe.Doe
Office : Chicago
Email : jsmith12#example.com
Username : Mike.Smith
Office : New York
Email : mike-smith#example.com
...
Something like for each ($user in $users) { ($user.Email = $userEmails | ? { $_.AccountEmail -eq $user.Username}).EmailAddress takes ages on large datasets.
Loop through one collection and store the values in a hash. Then loop through the other collection and pull the value back out of the hash. Something like:
$hash = #{}
$userEmails | %{ $hash[$_.AccountEmail] = $_.EmailAddress }
$users | %{ $_.Email = $hash[$_.Username] }
If you have other properties you can just store the original object:
$hash = #{}
$userEmails | %{ $hash[$_.AccountEmail] = $_ }
$users | %{
$item = $hash[$_.Username]
$_.Email = $item.EmailAddress
$_.Other = $item.SomethingElse
}
Or with loops instead of ForEach-Object including:
$hash = #{}
foreach($e in $userEmails) {
$hash[$e.AccountEmail] = $e
}
foreach($u in $users) {
$item = $hash[$u.UserName]
if ($item -ne $null) {
$u.Email = $item.EmailAddress
}
}
Related
This is bar graph i want to draw and i am struck in queries
My Database look like where i want to show population of country of 2020 Year
id | country_name | population | created_at
1 | USA | 2000000000 | 2020-02-04
2 | China | 2200000000 | 2020-02-04
3 | Russia | 12000000 | 2020-04-02
My Query look like this. I am just trying to build query but not getting result.Maybe there are some mistake.At first i making $countries variable to get all countries.
public function barChart(){
$countries=Country::get();
$graphic_header=['Year'];
$countrydata=[];
$actionDate=[];
$country_name=[];
foreach ($countries as $country) {
array_push($country_name, $country->name);
array_push($actionDate, date('Y', strtotime($country->created_at)));
$actionDate = array_unique($actionDate);
}
$graphic_header=array_merge($graphic_header,$country_name); //Dynamic Header
array_push($countrydata,$graphic_header);
foreach($actionDate as $d) {
$d = [$d];
$d = array_pad($d, sizeof($graphic_header), 0);
array_push($data, $d);
}
foreach ($countries as $country){
$date = date('Y', strtotime($country->created_at));
foreach ($data as $in =>$gd){
if ($date == $gd[0]) {
$index = (array_search($country->country_name, $graphic_header));
$country_data[$in][$index] = $country->population;
}
}
}
return response()->json([
'data'=> $country_data,
]);
}
simply use this groupBy collection method
$countries=Country::get();
$countries = $countries->groupBy('country_name');
$countries->toArray();
In the following script, it will print all the users of the groups. However, the domain name is missing (Some users are in different Windows domain)?
$computer = [ADSI]"WinNT://$server,computer"
$computer.psbase.children | ? {
$_.psbase.schemaClassName -eq 'group'
} | % {
$gn = $_.name.ToString()
write-host $gn
write-host "------"
$group =[ADSI]$_.psbase.Path
$group.psbase.Invoke("Members") | % {
$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)
}
}
Try fetching the SID instead of the name and translate that back to a username:
$computer.psbase.children | ? {
$_.psbase.schemaClassName -eq 'group'
} | % {
$gn = $_.name.ToString()
write-host $gn
write-host "------"
$group =[ADSI]$_.psbase.Path
$group.psbase.Invoke("Members") | % {
$bytes = $_.GetType().InvokeMember('objectSid', 'GetProperty', $null, $_, $null)
$sid = New-Object Security.Principal.SecurityIdentifier ($bytes, 0)
$sid.Translate([Security.Principal.NTAccount])
}
}
The result should include the computer or domain name.
We have a similar issue where there are accounts from different domains on the computers and we need the domain back. Unfortunately the SID fetch doesn't work I think for local accounts and the domains the computer used to be joined to in some cases, so it didn't return all results.
This was the best solution I found for us:
Admin = $_.GetType().InvokeMember("AdsPath", 'GetProperty', $null, $_, $null)
will return results like
WinNT://#domain#/#account#
or WinNT://#domain of computer#/#computer-name#/#account#
for local accounts
$servers= get-content 'C:\temp\work\localadmins\serverlist_in.txt'
$output = 'C:\temp\work\localadmins\serverlist_out.csv'
$results = #()
foreach($server in $servers)
{
$admins = #()
$group =[ADSI]"WinNT://$server/Administrators"
$members = #($group.psbase.Invoke("Members"))
$members | foreach {
$obj = new-object psobject -Property #{
Server = $Server
Admin = $_.GetType().InvokeMember("AdsPath", 'GetProperty', $null, $_, $null)
}
$admins += $obj
}
$results += $admins
}
$results | Export-csv $Output -NoTypeInformation
I am completely stumped. I am trying to add an embedded image to a notification email. The only scripts i can find are using .net to create a new email object.Can this only be done using .net to create an email object? Any Ideas
#################################################
# Configure the following variables….
# expireindays1 + 2 = At what count of days left on a password do you want a notification?
$smtpServer=”smtprelay.domain.com”
$expireindays1 = 5
#$expireindays2 = 1
$from = “Technology Helpdesk <technologyhelpdesk#domain.com>”
#################################################
#Get Users From AD who are enabled
Import-Module ActiveDirectory
$users = get-aduser -filter * -Properties enabled, GivenName, passwordneverexpires, passwordexpired, emailaddress, passwordlastset |where {$_.Enabled -eq “True”} | where { $_.PasswordNeverExpires -eq $false } | where { $_.passwordexpired -eq $false }
foreach ($user in $users)
{
$Name = (Get-ADUser $user | foreach { $_.Name})
$UserID = (Get-ADUser $user -Properties *).Samaccountname
$emailaddress = $user.emailaddress
$passwordSetDate = (get-aduser $user -properties passwordlastset | foreach { $_.PasswordLastSet })
$PasswordPol = (Get-AduserResultantPasswordPolicy $user)
# Check for Fine Grained Password
if (($PasswordPol) -ne $null)
{
$maxPasswordAge = ($PasswordPol).MaxPasswordAge
}
else
{
$maxPasswordAge = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge
}
$expireson = $passwordsetdate + $maxPasswordAge
$today = (get-date)
$daystoexpire = (New-TimeSpan -Start $today -End $Expireson).Days
#$subject=
$body = #'
#<html>
<body>
<img src="cid:image1"><br>
<b>$UserID : Your password will expire soon</b>
<br>
<br>
<br>
Dear $name,<br>
Your password will expire in $daystoexpire days. Please change your password before it expires to avoid password related problems. .<br>
<br>
<br>
<b>Password complexity rules:<br>
<br>
- Must be 7 or 8 characters long<br>
- Must contain at least 1 uppercase letter<br>
- Must contain at least 1 lowercase letter<br>
- Must contain at least 1 number<br>
- Must NOT contain repeating characters (e.g., aa, 11)</b><br>
<br>
<br>
Please use the following steps to change your password:<br>
- Press CTRL+ALT+DEL<br>
- Click Change a password…<br>
- Verify your User ID is correct, then type in your old and new passwords (you cannot use previously used passwords)<br>
- After the change is complete, you will be prompted that your password has been changed<br>
- If you have a Blackberry, iPhone, or iPad, those devices will need your new password as soon as your password has been changed<br>
<br>
If you have questions, or need assistance updating your passwords, please contact the Technology Help Desk. <br>
</body>
#</html>
'#
if (($daystoexpire -eq $expireindays1))
# -or ($daystoexpire -eq $expireindays2))
{
#Send-Mailmessage -smtpServer $smtpServer -from $from -to user#domain.com -subject $subject -body $body -bodyasHTML -priority High
####################################################################################################################
$images = #{
image1 = "c:\temp\action needed.png"
}
$params = #{
InlineAttachments = $images
#Attachments = 'C:\temp\action needed.png'
Body = $body
BodyAsHtml = $true
Subject = ”Your password will expire in $daystoExpire days”
From = "Technology Helpdesk <technologyhelpdesk#domain.com>"
To = 'user#domain.com'
#Cc = 'recipient2#domain.com', 'recipient3#domain.com'
SmtpServer = 'smtprelay.domain.com'
}
Send-MailMessage #params
}
}
This code does not use the dot net classes. I hope it helps.
$images = #{
image1 = 'c:\temp\test.jpg'
image2 = 'C:\temp\test2.png'
}
$body = #'
<html>
<body>
<img src="cid:image1"><br>
<img src="cid:image2">
</body>
</html>
'#
$params = #{
InlineAttachments = $images
Attachments = 'C:\temp\attachment1.txt', 'C:\temp\attachment2.txt'
Body = $body
BodyAsHtml = $true
Subject = 'Test email'
From = 'username#gmail.com'
To = 'recipient#domain.com'
Cc = 'recipient2#domain.com', 'recipient3#domain.com'
SmtpServer = 'smtp.gmail.com'
Port = 587
Credential = (Get-Credential)
UseSsl = $true
}
Send-MailMessage #params
BTW all credit to David Wyatt who created the code. He seems to be a good resource on powershell script.
I want to make a dynamic drop down in CI.I had done it in CI by directly passing the values from model With its design by concatenation the html.. But now i want it without the html i.e. the function just only should return the array ...
my before function was something like this...
function category() {
$sql = $this->db->query("select * from ss_category where parent_id='0'");
$result = $sql->result();
//print_r($result);die();
$output = array();
foreach ($result as $ra) {
$output=$this->get_child($ra->cat_id);
}
//print_r($output);die();
return $output;
}
function get_child($parent_id) {
//echo "select * from ss_category where parent_id=" . $parent_id;
$sql = $this->db->query("select * from ss_category where parent_id=" . $parent_id);
$r = $sql->result();
if (!empty($r)) {
foreach ($r as $s) {
$this->get_child($s->cat_id);
}
//print_r($child);
}
//print_r($r);
}
I want to make drop down something like this..
-parent 1
-child 1
-subchild 1
-child 2
-child 3
-subchild 1
-parent 2
-child 1
My table structure is like this..
+---------------------------------------------------------------+
| cat_id category_name cat_slug parent_id level description |
+---------------------------------------------------------------+
| 1 Elecotronics Electronics 1 description |
+---------------------------------------------------------------+
function parent_sort($categories)
{
foreach($categories as $item)
$childs[$item->parent_id][] = $item;
foreach($categories as $item)
if (isset($childs[$item->category_id]))
$item->childs = $childs[$item->category_id];
return $childs[0];
}
Is there a simple way using powershell to show all Local Windows Groups that are active on a machine and the users that are part of those groups? A second part of this question would be if it can be extended to look at more than one machine at a time.
In fact you can with the ADSI type shortcut and the WinNT moniker. Here's an example to list groups and members from your own machine:
$server="."
$computer = [ADSI]"WinNT://$server,computer"
$computer.psbase.children | where { $_.psbase.schemaClassName -eq 'group' } | foreach {
write-host $_.name
write-host "------"
$group =[ADSI]$_.psbase.Path
$group.psbase.Invoke("Members") | foreach {$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)}
write-host
}
Powershell does not have any inherent support for such a feature. However it's easy to wrap the "net localgroup" command with a couple of powershell functions and thus enable it in the pipeline.
Get Local Groups
function Get-LocalGroups() {
net localgroup | ?{ $_ -match "^\*.*" } | %{ $_.SubString(1) };
}
Get Local Group members
function Get-LocalGroupMembers() {
param ([string]$groupName = $(throw "Need a name") )
$lines = net localgroup $groupName
$found = $false
for ($i = 0; $i -lt $lines.Length; $i++ ) {
if ( $found ) {
if ( -not $lines[$i].StartsWith("The command completed")) {
$lines[$i]
}
} elseif ( $lines[$i] -match "^----" ) {
$found = $true;
}
}
}
Below is an improved version of Shay Levy's script which works for local groups with "orphaned" accounts which SIDs can't be resolved.
$server = "$env:COMPUTERNAME"
$computer = [ADSI]"WinNT://$server,computer"
$computer.psbase.children | where { $_.psbase.schemaClassName -eq 'group' } | foreach {
write-host $_.name
write-host "------"
$group =[ADSI]$_.psbase.Path
$group.psbase.Invoke("Members") | foreach {$_."GetType".Invoke().InvokeMember("Name", 'GetProperty', $null, $_, $null)}
write-host
}
Jay Levy's answer turned into a function :)
Function Get-LocalGroupMembers
{
Param(
[string]
$server = "."
)
Try
{
$computer = [ADSI]"WinNT://$( $Server ),computer"
$computer.psbase.children |
where {
$_.psbase.schemaClassName -eq 'group'
} |
ForEach {
$GroupName = $_.Name.ToString()
$group =[ADSI]$_.psbase.Path
$group.psbase.Invoke("Members") |
foreach {
$memberName = $_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null) -replace "WinNT:", ""
$props = #{
"LocalGroup" = $GroupName
"MemberName" = $memberName
}
$obj = New-Object -TypeName psobject -Property $props
Write-Output $obj
} # foreach members
} # foreach group
}
Catch
{
Throw
}
}
To get the local group members
Get-LocalGroupMembers
To get the local group members for another machine
Get-LocalGroupMembers -Server $Computer