Getting the error while inserting rows into azure table - powershell

I am trying to upload azure table row using PowerShell and I am receiving the below error. Could this be due to wrong Azure Storage powershell modules? I am using Azure.Storage 4.0.2 module.
Below is the Code:
# Getting all the resource group
$resource_group_list = Get-AzureRmResourceGroup
# Iterating through the resource group
foreach($resource_group_list_iterator in $resource_group_list){
# Since the solution applies for virtual machines,
# obtain the list of virtual machines for the resource group
$virtual_machine_list = get-azurermvm -ResourceGroupName $resource_group_list_iterator.ResourceGroupName
# Proceed only when resource group contains virtual machines
if(!($virtual_machine_list -eq $null)){
# Iterate through the virtual machine list
foreach($virtual_machine_list_iterator in $virtual_machine_list){
# Creat an unique ID by concatinating 'Resource Group name' and 'Virtual Machine name'
$unique_id = $resource_group_list_iterator.ResourceGroupName + $virtual_machine_list_iterator.name
#Write-Host $unique_id
$tag_list = $virtual_machine_list_iterator.Tags
$tag_list.GetEnumerator() | foreach {
#write-host $_.key
#Write-Host $_.value
#write-host ""
$partitionKey1 = $unique_id
if($_.key -eq 'owner' -and $_.value -eq 'ibm') {
#write-host "true"
$virtual_machine_name = $virtual_machine_list_iterator.Name.ToString()
$virtual_machine_resource_group_name = $resource_group_list_iterator.ResourceGroupName.ToString()
$virtual_machine_location = $virtual_machine_list_iterator.Location.ToString()
$virtual_machine_size = $virtual_machine_list_iterator.HardwareProfile.VmSize.ToString()
$virtual_machine_operating_system = $virtual_machine_list_iterator.StorageProfile.ImageReference.Offer.ToString()
$hash = #{}
#$hash.add('currentDate', $current_date)
$hash.Add('VM Name','VM')
$hash.Add('Resource Group',$virtual_machine_resource_group_name)
$hash.add('Location',$virtual_machine_location)
$hash.add('VM Size',$virtual_machine_size)
$hash.add('Operating System',$virtual_machine_operating_system)
Add-StorageTableRow -table $azure_table_object -partitionKey ("CA") -rowKey $unique_id -property $hash
}
}
}
}
}
Below is the exception that I received:
Exception calling "Execute" with "1" argument(s): "The remote server returned an error: (400)
Bad Request."
At C:\Program Files\WindowsPowerShell\Modules\AzureRmStorageTable\1.0.0.21\AzureRmStorageTableCor
eHelper.psm1:267 char:16
+ ... return ($table.CloudTable.Execute((invoke-expression "[Microsoft ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : StorageException
I have gone thru few online resources on how to troubleshoot, but I did not get any solution.

I use the fiddler to catch adding entity request on my side with your code. Then I could get the detail information that property name is invalid.
So please have a try to change the property name with following code.
$hash.Add('VM_Name','VM') #VM Name is invalid
$hash.Add('Resource_Group',$virtual_machine_resource_group_name) #Resource Group is invalid
$hash.add('Location',$virtual_machine_location)
$hash.add('VM_Size',$virtual_machine_size) #VM size is invalid
$hash.add('Operating_System',"windows")
Add-StorageTableRow -table $table -partitionKey ("CA") -rowKey $unique_id -property $hash
For more information about azure table property name please refer to this document.
poperty names are case-sensitive strings up to 255 characters in size. Property names should follow naming rules for C# identifiers.
Test Result:

Related

Find if a user is part of some distribution lists

I want to get a script working in powershell which takes a user's email and look it up against a few distribution lists to see if the user is a part of any of them. It should also check the nested distribution groups if any under the main distribution lists.
here's what I have but can't get it to work. Any help would be appreciated, I am fairly new to this.
# Prompt for user email address
$UserEmail = Read-Host -Prompt 'Please enter the user email address'
# Read the CSV file
$DistributionLists = Import-Csv -Path '.\DLs.csv'
# Loop through each Distribution List
foreach ($DL in $DistributionLists) {
# Get List of Distribution Group Members
$GroupMembers = Get-DistributionGroupMember -Identity $DL -ResultSize Unlimited
# Loop through each member
foreach ($Member in $GroupMembers) {
# Check if the user's email address matches
if ($Member.PrimarySmtpAddress -eq $UserEmail) {
# Output the matches
Write-Output "User $UserEmail is a part of $($DL.Name)"
}
}
}
but i get below error on execution:
Write-ErrorMessage : Cannot process argument transformation on parameter 'Identity'. Cannot convert value "" to type
"Microsoft.Exchange.Configuration.Tasks.DistributionGroupMemberIdParameter". Error: "Parameter values of type Microsoft.Exchange.Configuration.Tasks.DistributionGroupMemberIdParameter can't be empty. Specify a value, and try again.
Parameter name: identity"
At C:\Users\abcd\AppData\Local\Temp\tmpA_hrt0empv.vlz\tmpA_hrt0empv.vlz.psm1:1087 char:13
+ Write-ErrorMessage $ErrorObject
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-DistributionGroupMember], ParameterTransformationException
+ FullyQualifiedErrorId : [Server=BNxxxxxx5601,RequestId=abcdef5-1e51-d5f0-2a56-77b30f23bf3a,TimeStamp=Thu, 09 Feb 2023 14:04:01 GMT],Write-ErrorMessage
Error screenshot
The error statement informs us "-Identify $DL" is empty; $DL returns the entire object row and not just the name to be matched. To correct, refactor to $DL.DistributionLists where "DistributionLists" is the column header in the imported CSV file.
As we confirmed together you have already imported ExchangeOnlineManagement and made the connected to Exchange Online.... I've kept these in the code below for future reader reference.
# Pearl-script below:
# Import the ExchangeOnlineManagement module
Import-Module ExchangeOnlineManagement
# Connect to Exchange Online
Connect-ExchangeOnline
# Prompt for user email address
$UserEmail = Read-Host -Prompt 'Please enter the user email address'
# Read the CSV file
$DistributionLists = Import-Csv -Path '.\DLs.csv'
# Loop through each Distribution List
foreach ($DL in $DistributionLists) {
# Get List of Distribution Group Members
$GroupMembers = Get-DistributionGroupMember -Identity $DL.DistributionLists -ResultSize Unlimited
# Loop through each member
foreach ($Member in $GroupMembers) {
# Check if the user's email address matches
if ($Member.PrimarySmtpAddress -eq $UserEmail) {
# Output the matches
Write-Output "User $UserEmail is a part of $($DL.DistributionLists)"
}
}
}

GCP | disks.list method returning error when ran as part of a script

I am running this from PowerShell with gcloud CLI installed on my local Windows machine.
If I run disks.list by itself as followed, I get the expected output.
gcloud compute disks list `
--project=prj-d-jenkins-poc `
--filter="-users:*" `
--format="csv(name,sizeGb,zone,status,type,lastAttachTimestamp,lastDetachTimestamp)"
If I run it as part of a script, I get an error.
Script:
#Initiated OUTPUT variable as ArrayList to collect results
$OUTPUT = New-Object -TypeName "System.Collections.ArrayList"
$OUTPUT.Add("name,sizeGb,zone,status,type,lastAttachTimestamp,lastDetachTimestamp")
#Get list of accessible projects to PROJECTS
$PROJECTS = gcloud projects list --format="value(projectId)"
#Iterate through projects list
foreach ($i in $PROJECTS)
{
#Get list of unattached disks
$list = gcloud compute disks list `
--project=$i `
--filter="-users:*" `
--format="csv(name,sizeGb,zone,status,type,lastAttachTimestamp,lastDetachTimestamp)"
#If list is not empty, add it to OUTPUT
if ($list.count -gt 0){
$list = [System.Collections.ArrayList]$list #Convert a to ArrayList
$list.RemoveAt($list.0) #Remove first entry for a
$OUTPUT += $list #append a to OUTPUT
Write-Host "Unattached disks in $i wrote to OUTPUT variable."
}
else{ #If list is empty, skip
Write-Host "No unattached disks found in $i."
}
}
$OUTPUT
Error I get sometimes as it iterates through the project list:
python.exe : WARNING: The following filter keys were not present in any resource : users
At C:\Users\minh.tran\AppData\Local\Google\Cloud SDK\google-cloud-sdk\bin\gcloud.ps1:117 char:3
+ & "$cloudsdk_python" $run_args_array
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (WARNING: The fo...esource : users:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
I think this is because it was iterating through projects where there was no unattached disks, and that threw the error.
How do I modify my code so it will ignore these projects without unattached disks?

Update AddresBookPolicy AddressLists based on variable input

I am trying to update an Address Book Policy on Exchange Online.
Idea is that I parse some Address Lists and save these into a variable.
These could be passed into the Set-AddresBookPolicy.
So I start off with parsing these adresses:
$AddressLists = (Get-AddressList).Id | ? {$_ -like "*Company_1*"}
This results an array like \Company_1_Users, \Company_1_Contacts, \Company_1_DLs as expected.
I apply these with
Set-AddressBookPolicy -Identity "Company1" -AddressLists $AddressLists `
-RoomList "C1_Rooms" -GlobalAddressList "C1_GAL" -OfflineAddressBook "C1_OAB"
Result is an error:
WARNING: An unexpected error has occurred and a Watson dump is being generated: The operation can't be performed on this object because its status isn't valid.
The operation can't be performed on this object because its status isn't valid.
+ CategoryInfo : NotSpecified: (:) [Set-AddressBookPolicy], InvalidOperationException
+ FullyQualifiedErrorId : System.InvalidOperationException,Microsoft.Exchange.Management.SystemConfigurationTasks.SetAddressBookPolicy
+ PSComputerName : outlook.office365.com
I've tried converting it to a string (with -join ',') and have tried casting it, but I can't get further then an error (which then is of another kind).
If I copy the output and then type it into the command, it works. So that part is correct. However, I would like to automate this.
Does anyone know how I can correctly provide an input into the below cmdlet and have it running as expected?
EDIT: added full script below:
$AddressLists = #()
$AddressLists = (Get-AddressList).Id | ? {$_ -like "*Company_1*"}
$AddressLists = $AddressLists -join ',' #Adding this line just results in another error...
Set-AddressBookPolicy -Identity "Company1" -AddressLists $AddressLists `
-RoomList "C1_Rooms" -GlobalAddressList "C1_GAL" -OfflineAddressBook "C1_OAB"
The result of $AddressLists is an array (System.Array) with contents:
\Company_1
\Company_1Country1
\Company_1Country2
\Company_1Department1
\Company_1Department2
If your variable produces what you are saying...
$AddressLists = (Get-AddressList).Id | {$_ -like "*Company_1*"}
\Company_1_Users,
\Company_1_Contacts,
\Company_1_DLs
Then In Theory When You Add It Into a ForEach Loop It Should Work Accordingly. I Don't Have Exchange To Test It (by removing $updatecommand and leaving the execution command :o)
Change the settings of an address book policy in Exchange Online
<https://learn.microsoft.com/en-us/exchange/address-books/address-book-policies/change-the-settings-of-an-address-book-policy>
$AddressLists = ("\Company_1_Users", "\Company_1_Contacts", "\Company_1_DLs")
$iD = "Company1"
$rL = "C1_Rooms"
$gAL = "C1_GAL"
$oAB = "C1_OAB"
ForEach($AddressList in $AddressLists){
Write-Host "Without an Exchange Server, I'm Just Demonstating The Update Process"
Write-Host "The AddressList Being Updated Is -- $AddressList"
$updatecommand = "Set-AddressBookPolicy -Identity $iD -AddressLists $AddressList -RoomList $rL -GlobalAddressList $gAL -OfflineAddressBook $oAB"
Write-Host $updatecommand
}

How to automate removing Exchange Contacts in Office365

I am writing a powershell script that:
Compares two CSV files
Output files for: Changes, added, removed contacts
Update and add contacts
Remove contacts
The problem is when I try and removed contacts. Which is done by:
#Check for Removed Contacts
foreach($row in $File1_Data )
{
$data_found=0
foreach($id in $emails_id)
{
if ($row.ExternalEmailAddress -eq $id)
{
$data_found=1
}
}
if($data_found -eq 0 ) #Email Not Found
{ $row|Select-Object -Property ExternalEmailAddress|Export-Csv -Path $Removed_Contact -Append -NoTypeInformation}
}
Now I have a file with only the email addresses. The error comes when I try and run the command connected on the exchange server.
$RemoveContacts = Import-CSV ".\Removed Contacts_$((Get-Date).ToString('MMddyyyy')).csv"
$RemoveContacts | ForEach { Remove-MailContact -identity $_ -confirm:$false}
But I get the following error:
Cannot process argument transformation on parameter 'Identity'. Cannot convert the
"#{ExternalEmailAddress=testuser#testcompany.com}" value of type "Deserialized.System.Management.Automation.PSCustomObject"
to type "Microsoft.Exchange.Configuration.Tasks.MailContactIdParameter".
+ CategoryInfo : InvalidData: (:) [Remove-MailContact], ParameterBindin...mationException
+ FullyQualifiedErrorId : ParameterArgumentTransformationError,Remove-MailContact
+ PSComputerName : outlook.office365.com
$File_Data structure is in the format Microsoft requires.
and
$emails_id is the function that compares the two csv files. But that's not where the script breaks, that's just how i create the file.
What am I missing?
The error message is telling you that it can't convert the value of $_ to what it needs for -Identity parameter. Generally the -Identity parameter for most PS commandlets is going to be the human readable unique name of something. In this case, it would be an email address. With that said the error message is telling you that instead of $_ containing the string version of an email address, it contains a hash or dictionary object that contains a single property, ExternalEmailAddress.
So to make this work, change your $_ to $_.ExternalEmailAddress and now the call to Remove-MailContact will use the value of the ExternalEmailAddress property of the object in your ForEach loop.

Powershell try/catch/finally isn't executing right (or I've completely hosed it)

I have a script that checks for cyclic groups.
The script takes all groups in a domain (parent groups), checks the membership of those groups and adds any member with an objectClass of 'group' to an array (child groups).
The script then checks the child groups to see if the parent is a member of the child (yeah, it's allowed but still not a good idea).
I added a try/catch/finally block so I could get the actual group names instead of the truncated error message that PowerShell returns.
The problem is, the script stops at the first error it encounters instead of continuing on.
This is the first try/catch I've done, so please bear with me.
Here's the script:
$original_ErrorActionPreference = 'Continue'
$ErrorActionPreference = 'Stop'
Import-Module -Name ActiveDirectory
$domains = #('corp.com', 'dom1.corp.com', 'dom2.corp.com')
foreach($domain in $domains){
Write-Host $domain -ForegroundColor Yellow
$parents = Get-ADGroup -server $domain -Properties name,objectclass -Filter * #get all domain groups
write-host $parents.count
$table = #()
$pGroupCount = #($parents).Count
$record = #{
'Parent' = ''
'Child' = ''
'Nester' = ''
}
foreach($parent in $parents){
Write-Host $parent.name -ForegroundColor Green
The script works up to this point.
This is the part that fails-
try { #get members in the parent that are groups
$children = Get-ADGroupMember -Identity $parent | Where-Object{$_.ObjectClass -eq 'group'} | Select-Object name,distinguishedName,objectClass
} catch [Microsoft.ActiveDirectory.Management.Commands.GetADGroupMember]{
Write-Host $parent.name ' must be checked manually' -ForegroundColor blue -BackgroundColor Yellow
$parent.distinguishedName | Out-String -Width 4096 | Out-File -FilePath "$env:USERPROFILE\desktop\$domain-manualCheck.txt" -Width 5120 -Append
} finally {
$pGroupCount = $pGroupCount - 1
write-host $children.count ' - ' $children.name -ForegroundColor Gray
Write-Host $pGroupCount ' groups to go' -foregroundColor yellow
foreach($child in $children){ #get members in the children that are groups AND that have the same name as the parent
$nested = Get-ADGroupMember $child.name | Where-Object {$_.objectClass -eq 'group' -and $_.name -eq $parent.name}
$nestedCount = #($nested).count
if ($nestedCount -gt 0){
foreach($nester in $nested){
Write-Host $parent.name -ForegroundColor White
Write-Host $nestedCount -ForegroundColor Magenta
Write-Host $nester.name -ForegroundColor Cyan
$record.'Parent' = $parent.name
$record.'Child' = $child.name
$record.'Nester' = $nester.name
$objRecord = New-Object psobject -Property $record
$table += $objRecord
}
}
}
$table | Export-Csv -Path "$env:USERPROFILE\desktop\$domain-Group-Report.csv" -NoTypeInformation
$error | out-string -width 4096 | Out-File -FilePath "$env:USERPROFILE\desktop\$domain-Errors.txt" -Width 5120 -Append
}
}
}
$ErrorActionPreference = $original_ErrorActionPreference
As soon as the script hits the first group that has an issue, this is the error that's returned (#comments are added):
PS C:\Users\admin_j\Desktop> .\gtest.ps1
corp.com #current domain
283 #total group count
Exchange Servers #current group
6 - Exchange Install Domain Servers Exchange Install Domain Servers Exchange Install Domain Servers Exchange Install Domain Servers Exchange Install Domain Servers #6 groups within the parent, groups are from sub-domains
Exchange Install Domain Servers
282 groups to go
Get-ADGroupMember : Cannot find an object with identity: 'Exchange Install Domain Servers' under: 'DC=corp,DC=com'.
At C:\Users\admin_j\Desktop\gtest.ps1:46 char:15
+ $nested = Get-ADGroupMember $child.name | Where-Object $_.objectClass -eq ' ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Exchange Install Domain Servers:ADGroup) [Get-ADGroupMember], ADIdentityNotFoundException
+ FullyQualifiedErrorId : Cannot find an object with identity: 'Exchange Install Domain Servers' under: 'DC=corp,DC=com'.,Microsoft.ActiveDirectory.Management.Commands.GetADGroupMember
Why, instead of writing the bad group (in this case 'Exchange Install Domain Servers' under: 'DC=corp,DC=com'.) to a file, did the script stop? The group does indeed exist.
Should I add another block to catch any 'object not found' errors and send those to a file?
Thank you!
As Will's comment implies, you have indeed hosed your catch clause by specifying a type literal not matching an exception you'd ever expect thrown.
The general syntax for a catch clause is as follows
catch [catch-type-list] <statement block>
Where [catch-type-list] is an optional list of exception types that the associated statement block will act as an exception handler for.
That means, that this catch clause:
catch [Microsoft.ActiveDirectory.Management.Commands.GetADGroupMem‌​ber] {
# ...
}
Will only ever handle errors caused by an exception of the type [Microsoft.ActiveDirectory.Management.Commands.GetADGroupMem‌​ber] - this is of course not an exception type, and so the associated statement block will never execute.
In order for your catch clause to make sense in this context, specify a relevant exception type:
try{
Get-ADGroupMember -Identity $parent
}
catch [Microsoft.ActiveDirectory.Management.ADServerDownException]{
# DC is unreachable, abort
}
catch [Microsoft.ActiveDirectory.Management.ADIdentityResolutionException]{
# Group identity not resolved, add to list and continue
}
catch {
# Something else, completely unforeseen, happened, you might want to re-throw and return from your function
}
The last catch clause, in which the type list has been omitted is known as a general catch clause, and will handle any exception that didn't match any of the preceding catch clauses.