Error when checking array element in Powershell script : unexpected token 'eq' - powershell

I wish to go through a sharepoint list and if a property (a choice field named Status) is a certain value then change the author of that item.
Add-PSSnapin Microsoft.SharePoint.Powershell
$web = Get-SPWeb "http://site"
$library = $web.Lists["UserInfo"]
$newUser = $web.EnsureUser("user1")
$oldUser = $web.EnsureUser("user2")
foreach ($item in $library.Items)
{
#$userfield = New-Object Microsoft.SharePoint.SPFieldUserValue($web,$item["DocumentAuthorColumnInternalName"].ToString())
$userfield = New-Object Microsoft.SharePoint.SPFieldUserValue($web,$item["Author"].ToString())
$userfield = New-Object Microsoft.SharePoint.SPFieldUserValue($web,$item["Author"].ToString())
$login = $userfield.User.LoginName
#if ($login -eq $oldUser.LoginName)
if ($login -eq $oldUser.LoginName)
{
#if($item["Status"] eq 'Fully Implemented')
#{
$item["Author"] = $newUser
#if you are using default "Author" column, you need to set the following as well:
$item.Properties["vti_author"] = $newUser.LoginName
$item.UpdateOverwriteVersion() #this saves changes without incrementing the version
#}
}
$login = $null
}
$web.Dispose();
I can get it working but when I reach the line
if($item["Status"] eq 'Fully Implemented')
It causes an error
unexpected token 'eq'

Have you just missed the hyphen in eq? So it should be:
if($item["Status"] -eq 'Fully Implemented')
{
}

Related

I want to display a popup message of date contains in text file

I am having a script file to compare the my system login username and samaccountname. If the system login username and samaccountname is matched then my output is display popup message of my system login username. But the below script is working fine if the data is in excel file format. Due to some of user not having the ms office. Those used are doing browser based work. So i need to read the text file if the samaccountname matches contains in text file i want display the samaccountname and date.
Sample text file screenshot
$FilePath = 'd:\Alluserreport.xlsx'
$xl = New-Object -ComObject Excel.Application
$xl.Visible = $false
$wb = $xl.Workbooks.Open($filepath)
# get data from columns 2 and 3
$sheet = $wb.Worksheets['Alluserreport']
$rowMax = $sheet.UsedRange.Rows.Count
$data = for ($row = 2; $row -le $rowMax; $row++) {
[PsCustomObject] #{
SamAccountName = $sheet.Cells.Item($row, 2).Value2
LastLogonDate = [datetime]::FromOADate($sheet.Cells.Item($row, 3).Value2) # convert to DateTime object
}
}
# cleanup
$wb.close()
$xl.Quit()
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($wb)
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($sheet)
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($xl)
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
# filter for a specific username in the data
$user = $data | Where-Object { $_.SamAccountName -eq $env:USERNAME }
if ($user) {
$msgBody = "User: {0}`r`nLastLogon: {1}" -f $user.SamAccountName, $user.LastLogonDate
$msgTitle = "Test"
$msgButton = 'OK'
$msgImage = 'Asterisk'
$Result = [System.Windows.MessageBox]::Show($msgBody,$msgTitle,$msgButton,$msgImage)
}
else {
Write-Host "Not found"
}
Thanks for accepting the previous question.
Working with CSV files is even a lot easier than getting data from Excel.
Using your example:
# import the data from the file
$data = Import-Csv -Path 'd:\Alluserreport.csv'
# filter for a specific username in the data
$user = $data | Where-Object { $_.SamAccountName -eq $env:USERNAME }
if ($user) {
$msgBody = "User: {0}`r`nLastLogon: {1}" -f $user.SamAccountName, $user.'Expiration Date'
$msgTitle = "Test"
$msgButton = 'OK'
$msgImage = 'Asterisk'
$Result = [System.Windows.MessageBox]::Show($msgBody,$msgTitle,$msgButton,$msgImage)
}
else {
Write-Host "Not found"
}

How to fix Cannot index into a null array in PowerShell

I'm trying to convert my CSV file to Excel file with some Table format and style but I'm getting "Cannot index into a null array" for some reason. I'll be really appreciated if I can get any help or suggestion. Thanks
function Convert-to-Excel{
$params = #{
AutoSize = $true
TableStyle = 'Medium6'
BoldTopRow = $true
WorksheetName = 'Audit Log'
PassThru = $true
Path = "C:\AuditLogSearch\$((Get-Date).AddDays(-7).ToString('yyyy-MM-dd')) _ $(Get-Date -Format "yyyy-MM-dd") Audit-Log-Records11.xlsx"
}
$modifiedFile = Import-Csv "C:\AuditLogSearch\Modified-Audit-Log-Records.csv"
$actionReference = Import-Csv "C:\AuditLogSearch\Reference\Action.csv"
$xlsx = foreach ($u in $modifiedFile) {
$u.User = (Get-AzureADUser -ObjectId $u.User).DisplayName
New-Object PsObject -Property #{
User = $u.User
"Search Criteria" = $u."Search Criteria"
"Result Status" = $u."Result Status"
"Date & Time" = $u."Date & Time"
"Type of Action" = if (($actionReference | where-object { $_.Name -eq $u."Type of Action" }).Value -ne $null) { ($actionReference | where-object { $_.Name -eq $u."Type of Action" }).Value }
else { $u."Type of Action" }
} | Export-Excel #params
$ws = $xlsx.Workbook.Worksheets[$params.Worksheetname]
$ws.View.ShowGridLines = $false # => This will hide the GridLines on your file
Close-ExcelPackage $xlsx
}
}
You're closing the Excel Package on the first iteration of your loop hence why when it goes to the next it's trying to do something like this:
$null[$null] # => InvalidOperation: Cannot index into a null array
Try modifying your function so it looks like this instead:
First, construct the object[]:
$result = foreach ($u in $modifiedFile) {
$u.User = (Get-AzureADUser -ObjectId $u.User).DisplayName
New-Object PsObject -Property #{
User = $u.User
"Search Criteria" = $u."Search Criteria"
"Result Status" = $u."Result Status"
"Date & Time" = $u."Date & Time"
"Type of Action" = if (($actionReference.........
else { $u."Type of Action" }
}
}
Then export it to Excel:
$xlsx = $result | Export-Excel #params
$ws = $xlsx.Workbook.Worksheets[$params.Worksheetname]
$ws.View.ShowGridLines = $false # => This will hide the GridLines on your file
Close-ExcelPackage $xlsx
One thing to note, PassThru = $true on the $params means that instead of saving the Excel directly we want to save the object on a variable for "further manipulation" and by further manipulation what I mean is, in this case, hiding the GridLines of the worksheet ($ws.View.ShowGridLines = $false) and then closing the package (store it on the disk).
If you don't require to perform any modifications over the worksheet you can just remove the PassThru altogether and do:
$result | Export-Excel #params
Which will close the package and store the Excel on your disk.

Change SPWeb to a Particular Path Straight Away

I would like to change my PowerShell script to define a $spWeb value to a particular site straight away in a site collection, instead of going through the multiple foreach loops.
Is it possible?
Code sample:
$url = "http://testweb.com"
$siteCollection = Get-SPSite $url
$WebApp = $siteCollection.WebApplication
$url = $url+"/sites/site1"
foreach ($Site in $WebApp.Sites)
{
foreach($spWeb in $Site.AllWebs)
{
if ($spWeb.URL -eq $url)
{
//Skip previous foreach loops and declare $spWeb value with a fixed URL here
$users = $spWeb.SiteUserInfoList
$groups = $users.Items
$RList = $spWeb.Lists["Records"]
$RCount = 0
#GET Records
#$outputnewwebtext = "GET Records in $($spWeb.URL)"
#$outputnewwebtext |Tee-Object MRCE_Records.txt -Append
$query = New-Object Microsoft.SharePoint.SPQuery
$query.Query = '<Where><Eq><FieldRef Name="ContentType" /><Value Type="Computed">Item</Value></Eq></Where>'
$query.ViewAttributes = "Scope='RecursiveAll'";
$records = $Rlist.GetItems($query)
for ($intIndex =$records.Count - 1; $intIndex -gt -1; $intIndex--)
{
$RCount ++
}
$outputnewwebtext = "Records in $($spWeb.URL): $RCount`n"
}
}
}
Try Get-SPWeb command.
Get-SPWeb http://sp10/sites/team1

Receive Location Autohandling false email alerts

$exceptionList = Get-Content C:\Users\Dipen\Desktop\Exception_List.txt
$ReceiveLocations = Get-WmiObject MSBTS_ReceiveLocation -Namespace 'root\MicrosoftBizTalkServer' -Filter '(IsDisabled = True)' |
Where-Object { $exceptionList -notcontains $_.Name }
# Exit the script if there are no disabled receive locations
if ($ReceiveLocations.Count -eq 0)
{
exit
}
Example:
and
$mailBodyPT = ""
$mailTextReportPT = "There are: "
[STRING]$Subject = $SubjectPrefix + $BizTalkGroup
$mailTextReportPT += "in the BizTalk group: " + $BizTalkGroup + "."
#Send mail
foreach ($to in $EmailTo)
{
$Body = $HTMLmessage
#$SMTPClient = New-Object Net.Mail.SmtpClient($PSEmailServer)
$message = New-Object Net.Mail.MailMessage($from, $to, $Subject, $Body)
$message.IsBodyHtml = $true;
$SMTPClient.Send($message)
}
Question: when all RLs have the status "disabled" and all of these RLs are included in the exception list the value of the variable $ReceiveLocations should be false and I need to stop further processing in my script. (do nothing if all RLs are found in exception list, just exit)
But I'm still getting false email alerts. How can we set logic for not getting email alerts if there were no extra RLs found in $ReceiveLocations?
The value of the variable $ReceiveLocations is $null when your Get-WmiObject statement doesn't return results. $null doesn't have a property Count, hence the check $ReceiveLocations.Count -eq 0 fails and your script doesn't terminate before sending an e-mail.
You can avoid this issue in a number of ways, e.g. by putting $ReceiveLocations in the array subexpression operator:
if (#($ReceiveLocations).Count -eq 0) {
exit
}
or you could use the way PowerShell interprets values in boolean expressions (non-empty arrays become $true, $null becomes $false):
if (-not $ReceiveLocations) {
exit
}

Powershell DirectorySearcher Null Output

I'm writing a powershell script that searches for users inside an Active Directory OU and allows me to reset passwords by choosing matches from a list. I found a Tutorial that uses the System.DirectoryServices.DirectoryEntry and System.DirectoryServices.DirectorySearcher, and modified it like so:
$objDomain = New-Object System.DirectoryServices.DirectoryEntry("LDAP:\\[REDACTED]")
##ReadSTDIN
$strSearch = Read-Host -Prompt "Search"
$strCat = "(&(objectCategory=User)(Name=*" + $strSearch + "*))"
## Search Object
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = $objDomain
$objSearcher.PageSize = 1000
$objSearcher.Filter = $strCat
$objSearcher.SearchScope = "Subtree"
#Load Required Properties into the dynObjLink
$objSearcher.PropertiesToLoad.Add("name")
$objSearcher.PropertiesToLoad.Add("userPrincipalName")
$objSearcher.PropertiesToLoad.Add("SamAccountName")
##Magical Search Function
$colResults = $objSearcher.FindAll()
$colResults.PropertiesLoaded
#for every returned userID add them to a table
ForEach ($objResult in $colResults)
{$a++
$objResult.count
$objItem = $objResult.Properties
$objItem.name
$objItem.userPrincipalName
$results.Add($a, $objItem.name + $objItem.userPrincipalName + $objItem.SamAccountName)
}
#Print Table
$results | Format-Table -AutoSize
This works well enough, but when it prints data I can only get the "first name" value of anything that comes back. Everything else becomes NULL and I can't figure out why.
Name Value
---- -----
3 {James3 [REDACTED], $null, $null}
2 {James2 [REDACTED], $null, $null}
1 {James1 [REDACTED], $null, $null}
I've tried different kinds of authentication and manipulating values, but the DirectorySearcher object only seems to collect the "name" value of any record it returns, no matter what I load into it. Help?
Here's a bit shorter (and PowerShell v2-compatible) way of doing this:
#requires -version 2
param(
[Parameter(Mandatory=$true)]
[String] $SearchPattern
)
$searcher = [ADSISearcher] "(&(objectClass=user)(name=$SearchPattern))"
$searcher.PageSize = 1000
$searcher.PropertiesToLoad.AddRange(#("name","samAccountName","userPrincipalName"))
$searchResults = $searcher.FindAll()
if ( $searchResults.Count -gt 0 ) {
foreach ( $searchResult in $searchResults ) {
$properties = $searchResult.Properties
$searchResult | Select-Object `
#{Name = "name"; Expression = {$properties["name"][0]}},
#{Name = "sAMAccountName"; Expression = {$properties["samaccountname"][0]}},
#{Name = "userPrincipalName"; Expression = {$properties["userprincipalname"][0]}}
}
}
$searchResults.Dispose()
Note that there's no need to build a list and output afterwards. Just output each search result. Put this code in a script file and call it:
PS C:\Scripts> .\Searcher.ps1 "*dyer*"
If you omit the parameter, PowerShell will prompt you for it (because the parameter is marked as mandatory).
try using Properties matching to the PropertiesToLoad
$entry = new-object -typename system.directoryservices.directoryentry -ArgumentList $LDAPServer, "ldap", "esildap"
$entry.Path="LDAP://OU=childOU,OU=parentOU,DC=dc1,DC=dc2"
$searcher = new-object -typename system.directoryservices.directorysearcher -ArgumentList $entry
$searcher.PropertiesToLoad.Add('samaccountname')
$searcher.PropertiesToLoad.Add('mail')
$searcher.PropertiesToLoad.Add('displayname')
$objs = $searcher.findall()
foreach($data in $objs)
{
$samaccountname = $data.properties['samaccountname'][0] + ''
$mail = $data.properties['mail'][0] + ''
$displayname = $data.properties['displayname'][0] + ''
}
when accessing the properties of the resultset you get a System.DirectoryServices.ResultPropertyValueCollection type for each property
to get a string value for passing to a database the property value access the zero index of the object