How to get creation date in sitecore with powershell - powershell

I wrote a script in order to replace the "$date" in release date of many Sitecore items with their creation date (created).
I have a problem to get this field from Sitecore.
I tried this:
$rootItem = Get-Item master:/content
$sourceTemplate = Get-Item "/sitecore/content/.../item 1"
foreach($field in $sourceTemplate.Fields) {
if (($field -ne $null) -And ($field -like '$date')) {
$sourceTemplate.Editing.BeginEdit()
$CreatedDate = .......
$field.Value = [sitecore.dateutil]::ToIsoDate($CreatedDate)
$sourceTemplate.Editing.EndEdit()
}
}
I also tried to get this field by ID but it doesn't work.
Does someone have an idea please?
Thank you

If you want to check Sitecore built-in fields, you need to call $sourceTemplate.Fields.ReadAll(); first.
You should compare value of the field with $date string, not the field itself.
Then just get the string which is stored in the __Created field instead of getting date and then formatting it back to ISO date string.
And the last thing - don't call Editing.BeginEdit() and Editing.EndEdit() mutliple times for the same item - Sitecore runs some havily operations when it's called so make sure you only call it once per every item which needs it.
$sourceTemplate = Get-Item "/sitecore/content/home/test"
$sourceTemplate.Fields.ReadAll();
$editing = $false
foreach($field in $sourceTemplate.Fields) {
if ($field.Value -eq '$date') {
if (!$editing) {
$editing = $true
$sourceTemplate.Editing.BeginEdit();
}
$field.Value = $sourceTemplate.Fields["__Created"].Value
}
}
if ($editing) {
$edited = $sourceTemplate.Editing.EndEdit();
}

Related

Powershell excel paste vaule

I have one excel file with a few sheets in it. Im trying to combine all of them into one sheet. I have code that does this, but the issue im having now is now the sheets have formulas on them. So when it copies to the new sheet it doesnt copy over the values, but copies the formulas. I was reading online you can do this pastespecial, but i cant get it working. Does anyone have code on how can i copy one sheet to another, but keep the values. The one issue is the sheets have differnt amount of rows so im not sure how what the range would be. I have tried many things and i just can figure it out.
This is using the excel.application
To questions, the thing is i cant figure out the .PasteSpecial.
Here is the code now that copies it to a sheet called combine.
$wb = $excel.Workbooks.Open($location)
$newSheetName = 'Combine'
$xlCellTypeLastCell = 11
$targetSheet = $wb.Sheets.Add()
$targetSheet.Name = $newSheetName
$includeHeader = $true
foreach ($sh in $wb.Sheets) {
$statename = $sh.Name
if($sh.name -eq "Available" -or $sh.name -eq "Eligible"){
}else{
$sh.autofiltermode = $false
$sourceRange = $sh.UsedRange
if ($sourceRange.Rows.Count -le 1) { continue }
# if ($sourceRange.Rows.Count -le 1 -or $sh.Name -eq $newSheetName) {continue}
$targetLastCell = $targetSheet.UsedRange.SpecialCells($xlCellTypeLastCell)
if ($includeHeader) {
[Void]$sourceRange.PasteSpecial($targetLastCell)
}
else {
$columnOffset = - $targetLastCell.Column + 1
$targetCell = $targetLastCell.Offset(1, $columnOffset)
$newRowCount = $sourceRange.Rows.Count - 1
[Void]$sourceRange.Offset(1, 0).Resize($newRowCount).Copy($targetCell)
}
$includeHeader = $false
}
}
This does work with headers, but at this point i dont really care about those. I will say UsedRange also misses me up. So right now it i just use the .copy and from reading online i need to use the pasteSpecial.

How to check if the Array date is in specific pattern

I am able to check a single date using below working code.
$date = "01/APR/2010:10:10:10"
$format = 'dd/MMM/yyyy:HH:mm:ss'
if(![datetime]::TryParseexact($date,$format,[system.Globalization.DateTimeFormatInfo]::InvariantInfo,[system.Globalization.DateTimeStyles]::None, [ref]$result ))
{
echo "Date format failed"
}
But I am unable to verify if the dates are in an array, like this
$date = #("01/APR/2010:10:10:10","01/MAY/2010:10:10:10")
You just need to iterate through dates one by one.
$dates = #("01/APR/2010:10:10:10","01/MAY/2010:10:10:10")
foreach ($date in $dates) {
# add verification code here
}

How to avoid errors when casting null REST data to datetime

I am using a REST API to pull invoice data, from an external company, into an Excel file using PowerShell. I can pull the data just fine using the Invoke-RestMethod. Although, when it pulls the datetime fields, it is in a format I do not prefer. To automate my job as much as possible, is there a way to cast the data to datetime. Keep in mind, not every field has data so there are null fields which cause the errors. I basically want to pull all data, if it has an ugly-formatted datetime, change it to the way I want to see it, or if it is empty, just continue on.
I have tried [nullable[datetime]] (found it on google somewhere), but that throws other errors. I have tried using an 'IF' but that also generates in out set of syntax errors.
$out = Invoke-RestMethod -Uri $assetsURL
#$out.Invoices | Export-Excel $outputcsv
$out.Invoices |
Select-Object * |
ForEach-Object {
$Properties = [ordered]#{
InvoiceNumber = $_.InvoiceNumber
DueDate = $_.DueDate #[datetime]::parseexact($_.DueDate, 'yyyy-MM-ddThh:mm:ss', $null).ToString('yyyy-MM-dd')
Currency = $_.Currency
TotalDue = $_.TotalDue
PeriodFrom = $_.PeriodFrom #[datetime]::parseexact($_.PeriodFrom,'yyyy-MM-ddThh:mm:ss', $null).ToString('yyyy-MM-dd')
PeriodTo = $_.PeriodTo #[datetime]::parseexact($_.PeriodTo,'yyyy-MM-ddThh:mm:ss', $null).ToString('yyyy-MM-dd')
BillingName = $_.BillingName
BillingAddress = $_.BillingAddress
BillingAttentionTo = $_.BillingAttentionTo
BillingCity = $_.BillingCity
BillingState = $_.BillingState
BillingPostalCode = $_.BillingPostalCode
RemitToName = $_.RemitToName
RemitToAddress = $_.RemitToAddress
RemitToAttentionTo = $_.RemitToAttentionTo
RemitToCity = $_.RemitToCity
RemitToState = $_.RemitToState
RemitToPostalCode = $_.RemitToPostalCode
Lease = $_.Lease
Schedule = $_.Schedule
CreatedDate = $_.CreatedDate #[datetime]::parseexact($_.CreatedDate, 'yyyy-MM-ddThh:mm:ss', $null).ToString('yyyy-MM-dd')
}
New-Object psobject -Property $Properties
} | Export-Excel $outputcsv
Just updating because I may not have been clear on what the issue is. In the columns 'DueDate', 'PeriodFrom', 'PeriodTo', and 'CreatedDate', these are all pulled from the REST API. 'DueDate' and 'CreatedDate' seem to be properly populated but 'PeriodFrom' and 'PeriodTo' may or may not have a date.
Currently, without any trickery, the date (if it exists) returns as:
2019-09-05T00:00:00
I would like to return an empty field if it does not exist or return the date in the like the following if it does exit:
2019-09-05
You can use TryParseExact:
ForEach-Object {
$parsedDate = [datetime]::MinValue
$Properties = [ordered]#{ # remove the CreatedDate from the HashTable
[...]
if ([datetime]::TryParseExact($_.CreatedDate,'yyyy-MM-ddThh:mm:ss',
[System.Globalization.CultureInfo]::InvariantCulture,
[System.Globalization.DateTimeStyles]::None,[ref]$ParsedDate))
{$Properties.Add("CreatedDate", $parsedDate.ToString("yyyy-MM-dd"))}
}
else {
$Properties.Add("CreatedDate",$null)
}
Note that you can add array of string formats instead of a single string, for example:
[String[]]$DateStrings = "M/dd/yyyy h:mmtt","M/d/yyyy h:mmtt","MM/d/yyyy h:mmtt"
Then it would be:
[datetime]::TryParseExact($_.CreatedDate,$DateStrings...)

EWS Delete PhoneNumber Entry on Contact

I try to Delete an phone number Entry within an contact while using the ExchangeWebService and powershell.
I can create new Contacts with Numbers and so on. I can even change those numbers. But i can set then to $null or "".
It always gives me Exception calling "Update" with "1" argument(s): "An object within a change description must contain one and only one property to modify."
I understand that im not allowed to set it to "" or null. But there have to be a way to delete a phone number entry.
So may be there is someone out there to help me with this issue.
So far i check if there is a change in the phone number and only update it where there is.
$enumBusinessPhoneValue = [Microsoft.Exchange.WebServices.Data.PhoneNumberKey]::BusinessPhone
if($c.PhoneNumbers[$enumBusinessPhoneValue] -ne "" -and $c.PhoneNumbers[$enumBusinessPhoneValue] -ne $null){
if($busPhone -ne ""){
if($c.PhoneNumbers[$enumBusinessPhoneValue] -ne $busPhone){
echo "="
$c.PhoneNumbers[$enumBusinessPhoneValue] = $busPhone
}
} else {
$c.PhoneNumbers[$enumBusinessPhoneValue] = ""
}
} else {
if($busPhone -ne ""){
$c.PhoneNumbers[$enumBusinessPhoneValue] = $busPhone
}
}
$c.Update([Microsoft.Exchange.WebServices.Data.ConflictResolutionMode]::AlwaysOverwrite)
The problem lies in this line $c.PhoneNumbers[$enumBusinessPhoneValue] = "" even if i put in $null i get the same error.
Greetings
skratter
You need to use the Extended Property for the Business Phone in this case (this is the same as for EmailAdddresses https://blogs.msdn.microsoft.com/emeamsgdev/2012/05/17/ews-managed-api-how-to-remove-email1-email2-email3-from-a-contact/) eg
$PidTagBusinessTelephoneNumber = new-object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(0x3A08,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::String);
$c.RemoveExtendedProperty($PidTagBusinessTelephoneNumber)
$c.Update([Microsoft.Exchange.WebServices.Data.ConflictResolutionMode]::AlwaysOverwrite)

Writing a hashtable value to an attribute

Powershell newbie here, my first script.
I have user objects with an AD custom attribute named tvCode with a values of 123456 or 6787682 or 983736 etc.
I would like to script something that will get the tvCode value from the user object
When:
123456 = Sony
6787682 = Samsung
9837343 = LG
Write the value of "Sony" or "Samsung" or "LG" to the "City" attribute of the user object.
Looks like i may need to use a hashtable.
If possible do this for a specific OU
hope this makes sense
thanks
function Convert-TVCode {
Param
(
[parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true)]
[String[]]
$Code
)
Process {
foreach ($C in $Code) {
switch ($C) {
"123456" {$brand = "Sony"}
"6787682" {$brand = "Samsung"}
"9837343" {$brand = "LG"}
default {
$brand = $null
Write-Warning "$C not included in switch statement. Returning"
return
}
}
if ($brand) {
Write-Verbose "Code '$C' matched to Brand '$brand' -- searching for users to update"
Get-ADUser -Filter "tvCode -eq '$C'" | Set-ADUser -Replace #{tvCode=$brand}
}
}
}
}
This function will allow you to update any users that have their tvCode attribute set as one of the target numerical values. You can have it hit multiple codes at once as well.
Examples:
Convert-TVCode -Code 123456
Convert-TVCode -Code 123456,6787682
Convert-TVCode -Code 123456,6787682,9837343 -Verbose
Update the switch statement in the function to customize it to your actual values and let me know if you have any questions!