Can't check ArchiveStatus for mailbox - if-statement

I am building a script that'll check if ArchiveStatus for an Office 365 mailbox is active or not. I am able to pull the data, but my if/else statement doesn't seem to work. This is what I have so far:
$Data = Get-Mailbox -Identity "MailboxName" | ft name,*Archive*
$Data
if ($_.ArchiveStatus -eq $true) {
Write-Host "Archive Enabled"
} else{
Write-Host "Archiving Disabled"
}
No matter what mailbox I search up, the result is always "Archiving Disabled" even if the console shows user enabled.

The current object variable ($_) is only available in a pipeline context. Your if statement is outside a pipeline, so $_ doesn't exist, meaning that $_.ArchiveStatus evaluates to $null, which is interpreted as $false in the comparison.
Change this:
$Data = Get-Mailbox -Identity "MailboxName" | ft name,*Archive*
$Data
if ($_.ArchiveStatus -eq $true) {
Write-Host "Archive Enabled"
} else {
Write-Host "Archiving Disabled"
}
into this:
$Data = Get-Mailbox -Identity "MailboxName"
$Data | ft name,*Archive*
if ($Data.ArchiveStatus -eq $true) {
Write-Host "Archive Enabled"
} else {
Write-Host "Archiving Disabled"
}
and the problem should disappear.

So I was able to figure it out with help from #Ansgar Wiechers. The -eq $true wasn't working because it was either Active or None. When i created the variable for this it worked. The working code is below:
$Data = Get-Mailbox -Identity "MailboxName"
$Data | ft name, ArchiveStatus
$Status = "Active"
if($Data.ArchiveStatus -eq $Status) {
Write-Host "Archive Enabled"
} Else {
Write-Host "Archiving Disabled"
}
Thank you for your help!!

Related

Add DOMAIN\Domain Admins group as Full Access to the orphaned Home Directory?

The below script was created by the great https://stackoverflow.com/users/9898643/theo to list all orphaned HomeDirectory:
$ServerHomeDirShare = "\\FileServer\HomeDir$"
$filter = "(Enabled -eq 'true')"
# get all user accounts from AD; only SamAccountName required
$users = Get-ADUser -Filter $filter | Select-Object -ExpandProperty SamAccountName
Get-ChildItem -Path $ServerHomeDirShare -Directory |
Where-Object { $users -notcontains ($_.Name -replace '^(\w+\.\w+).*', '$1') } |
Select-Object -Property Name, FullName,
#{ n = 'LastAccessTime'; e = { $_.LastAccessTime.ToString('yyyy-MM-dd HH:mm:ss') } },
#{ n = "Directory Size (MB)"; e = {
Try {
$Size = (Get-ChildItem -Path $_.FullName -Recurse -ErrorAction Stop |
Measure-Object Length -Sum).Sum / 1MB
[math]::Round($Size, 2)
}
Catch {
"ERROR: $($_.Exception.Message)"
}
}
} |
Export-Csv -NoTypeInformation -Path C:\UserProfilesNotExist-Size.csv
However, there is one more issue that needed fixing, to add DOMAIN\Domain Admins AD group as Full Access to the directory ACL, BUT ONLY when the directory is not accessible or throwing error.
$FullAccessADGroup = "DOMAIN\Domain Admins"
function Take-Ownership
{
param (
[String]$Folder
)
takeown.exe /A /F $Folder
$CurrentACL = Get-Acl $Folder
write-host "`n`t...Adding NT Authority\SYSTEM to $Folder" -ForegroundColor Yellow
$SystemACLPermission = "NT AUTHORITY\SYSTEM", "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow"
$SystemAccessRule = new-object System.Security.AccessControl.FileSystemAccessRule $SystemACLPermission
$CurrentACL.AddAccessRule($SystemAccessRule)
write-host "`t...Adding Infrastructure Services to $Folder" -ForegroundColor Yellow
$AdminACLPermission = $FullAccessADGroup, "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow"
$SystemAccessRule = new-object System.Security.AccessControl.FileSystemAccessRule $AdminACLPermission
$CurrentACL.AddAccessRule($SystemAccessRule)
Set-Acl -Path $Folder -AclObject $CurrentACL
}
function Test-Folder($FolderToTest) {
$error.Clear()
$ErrorArray = #()
Get-ChildItem $FolderToTest -Recurse -ErrorAction SilentlyContinue | Select-Object FullName
if ($error) {
$ErrorArray = $error + $ErrorArray
foreach ($err in $ErrorArray) {
if ($err.FullyQualifiedErrorId -eq "DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand") {
Write-Host Unable to access $err.TargetObject -ForegroundColor Red
Write-Host Attempting to take ownership of $err.TargetObject -ForegroundColor Yellow
Take-Ownership($err.TargetObject)
Test-Folder($err.TargetObject)
}
}
}
}
Test-Folder $source
Because even though I am using DOMAIN\Administrator account to execute the script above, I cannot get the directory size or even opened the directory via the UNCPath, this is the error:
ERROR: Access to the path '\\FileServer\HomeDir$\Jane.Liz.V2' is denied.
ERROR: Access to the path '\\FileServer\HomeDir$\Lisa.Chan.V5' is denied.
ERROR: Access to the path '\\FileServer\HomeDir$\Carolline.Marce.V6' is denied.
...

Not taking the Else-if input powershell with Switch statement

I need help with PowerShell code. I have to update a couple of programs using PowerShell, but I am getting errors while running the script.
Inputs to the code are 1 and 0 for Switch condition and other inputs are foo, boo, Oracle to be updated, based on condition software will be updated.
$param = Read-Host -Prompt "Enter the input 1 or 0"
[bool]$upg = $true
$sftp = Read-Host "Please Enter the softwre to update"
switch ($param)
{
0{
Write-Output "Today is monday"
}
1
{
$prm_prd = Read-Host -Prompt "Are you going for operation upgrade"
if ($prm_prd -eq $upg)
{
Write-Output "System upgrade"
if ($sftp -eq 'foo')
{
Write-Output "foo upgrade"
}
elseif ( $sftp -eq 'boo')
{
Write-output "boo upgrade"
}
elseif ( $sftp -eq 'Oracle')
{
Write-output "oracle upgrade"
}
}
}
}
Didn't you post some form of this before? Elseif not else-if.

Iterate through PSOObject

I am writing a script where Block Devices attached to a EC2 instance are matched and then a corresponding tag is set.
I have following PSOObject and visualization in the console
New-Object PSObject -Property #{
Disk = $Disk;
Partitions = $Partitions;
DriveLetter = If ($DriveLetter -eq $null) { "N/A" } Else { $DriveLetter };
EbsVolumeId = If ($EbsVolumeID -eq $null) { "N/A" } Else { $EbsVolumeID };
Device = If ($BlockDeviceName -eq $null) { "N/A" } Else { $BlockDeviceName };
VirtualDevice = If ($VirtualDevice -eq $null) { "N/A" } Else { $VirtualDevice };
VolumeName = If ($VolumeName -eq $null) { "N/A" } Else { $VolumeName };
}
} | Sort-Object Disk | Format-Table -AutoSize -Property Disk, Partitions, DriveLetter, EbsVolumeId, Device, VirtualDevice, VolumeName
Now I have following simple New-EC2tag command tagging the instance.
New-EC2Tag -Resource $InstanceId -Tags #{ Key = $DriveLetter; Value = $BlockDeviceName}
Basically it just writes the C: Drive and I believe I have to iterate through the PSObject to basically also set the corresponding drives.
I would bge grateful for any help.

how can we unpublish item with its subitem for one particular language in sitecore?

we have option in ribbon publish - > change but that is not unpublishing subitems .
how can we unpublish item with its subitem for one particular language in sitecore ?
Thanks
Approach 1:
In the Publish ribbon, click the Change button and UNCHECK Publishable on the Item tab. Now delete the parent item with sub-items and the item will be removed from the published DB. Next go back to the item and CHECK Publishable, then publish the item only in the language you want.
Approach 2:
Use the database selector in the Sitecore shell (bottom right corner) and select your publishing target DB (e.g. "web"). GO into that tree, find the item in the language and delete that version. After that you'll need to go to your public site's cache page and clear that cache manually: http://host/sitecore/admin/cache.aspx
Approach 3:
Delete the item in the master DB, publish the parent, restore it form the recycle bin, publish it again live but not in the language you don't want.
some script is also fine :)
just publish site after use it
function GetItemDatasources {
[CmdletBinding()]
param([Item]$Item)
# grab all datasources that are not header and footer elements
return Get-Rendering -Item $item -FinalLayout -Device (Get-LayoutDevice -Default) |
Where-Object { -not [string]::IsNullOrEmpty($_.Datasource)} |
Where-Object { $_.Placeholder -ne 'Above Page Content' } |
Where-Object { $_.Placeholder -ne 'Below Page Content' } |
ForEach-Object { Get-Item "$($item.Database):" -ID $_.Datasource }
# ForEach-Object { Write-Host ($_ | Format-List | Out-String) }
}
$location = get-location
$languages = Get-ChildItem "master:\sitecore\system\Languages"
$currentLanguage = [Sitecore.Context]::Language.Name
$langOptions = #{};
foreach ($lang in $languages) {
$langOptions[$lang.Name] = $lang.Name
}
$result = Read-Variable -Parameters `
#{ Name = "destinationLanguages"; Title="Language(s) for clean up "; Options=$langOptions; Editor="checklist"; },
#{ Name = "includeSubitems"; Value=$false; Title="Include Subitems"; Columns = 4;} `
-Description "Select an languages that should be cleanup" `
-Title "Cleanup Language" -Width 650 -Height 660 -OkButtonName "Proceed" -CancelButtonName "Cancel" -ShowHints
if($result -ne "ok") {
Exit
}
Write-Host "destinationLanguages = $destinationLanguages"
$items = #()
$items += Get-Item $location
# add optional subitems
if ($includeSubitems) {
$items += Get-ChildItem $location -Recurse
}
# Remove any duplicates, based on ID
$items = $items | Sort-Object -Property 'ID' -Unique
$items | ForEach-Object { Write-Host ($_.ItemPath | Sort-Object | Format-List | Out-String) }
$message = "You are about to cleanup <span style='font-weight: bold'>$($items.Count) item(s)</span> with the following options:<br>"
$message += "<br><table>"
$message += "<tr><td style='width: auto'>Languages:</td><td>$destinationLanguages</td></tr>"
$message += "<tr><td style='width: auto'>Include Subitems:</td><td>$includeSubitems</td></tr>"
$message += "</table>"
$message += "<br><p style='font-weight: bold'>Are you sure?</p>"
$proceed = Show-Confirm -Title $message
if ($proceed -ne 'yes') {
Write-Host "Canceling"
Exit
}
Write-Host "Proceeding with execution"
$items | ForEach-Object { Remove-ItemVersion -Item $_ -Language $destinationLanguages -ExcludeLanguage "en*" }
I did this
function GetItemDatasources {
[CmdletBinding()]
param([Item]$Item)
# grab all datasources that are not header and footer elements
return Get-Rendering -Item $item -FinalLayout -Device (Get-LayoutDevice -Default) |
Where-Object { -not [string]::IsNullOrEmpty($_.Datasource)} |
Where-Object { $_.Placeholder -ne 'Above Page Content' } |
Where-Object { $_.Placeholder -ne 'Below Page Content' } |
ForEach-Object { Get-Item "$($item.Database):" -ID $_.Datasource }
# ForEach-Object { Write-Host ($_ | Format-List | Out-String) }
}
$location = get-location
$languages = Get-ChildItem "master:\sitecore\system\Languages"
$currentLanguage = [Sitecore.Context]::Language.Name
$langOptions = #{};
$actions = #{};
$actions["Unpublish"] = "1";
$actions["Publish"] = "";
foreach ($lang in $languages) {
$langOptions[$lang.Name] = $lang.Name
}
$result = Read-Variable -Parameters `
#{ Name = "destinationLanguages"; Title="Language(s) for publich/unpublish"; Options=$langOptions; Editor="checklist"; },
#{ Name = "includeSubitems"; Value=$false; Title="Include Subitems"; Columns = 4;},
#{ Name = "action"; Value="1"; Title="Action"; Options=$actions; Tooltip="Unpublish: Set language as unblishded on all langauge vestions.<br>Publish: Set language as publishded on all langauge vestions."; }`
-Description "Select languages that should be proceed during updates" `
-Title "Language Publish - Unpublish" -Width 650 -Height 660 -OkButtonName "Proceed" -CancelButtonName "Cancel" -ShowHints
if($result -ne "ok") {
Exit
}
Write-Host "destinationLanguages = $destinationLanguages"
$items = #()
$items += Get-Item $location
# add optional subitems
if ($includeSubitems) {
$items += Get-ChildItem $location -Recurse
}
# Remove any duplicates, based on ID
$items = $items | Sort-Object -Property 'ID' -Unique
$items | ForEach-Object { Write-Host ($_.ItemPath | Sort-Object | Format-List | Out-String) }
$message = "You are about to publish/unpublish <span style='font-weight: bold'>$($items.Count) item(s)</span> with the following options:<br>"
$message += "<br><table>"
$message += "<tr><td style='width: auto'>Languages:</td><td>$destinationLanguages</td></tr>"
$message += "<tr><td style='width: auto'>Include Subitems:</td><td>$includeSubitems</td></tr>"
$message += "</table>"
$message += "<br><p style='font-weight: bold'>Are you sure?</p>"
$proceed = Show-Confirm -Title $message
if ($proceed -ne 'yes') {
Write-Host "Canceling"
Exit
}
Write-Host "Proceeding with execution"
$items | ForEach-Object {
$vitems = Get-Item $_.ID -Language $destinationLanguages -Version *
$vitems | ForEach-Object {
$_.Editing.BeginEdit()
$_["__Hide version"] = $action
$_.Editing.EndEdit()
}
}

Powershell function to replace or add lines in text files

I'm working on a powershell script that modifies config files. I have files like this:
#####################################################
# comment about logentrytimeout
#####################################################
Logentrytimeout= 1800
who should look like this:
#####################################################
# comment about logentrytimeout
#####################################################
Logentrytimeout= 180
disablepostprocessing = 1
segmentstarttimeout = 180
If there is a key set(Logentrytimeout), just update it to the given value. Ignore comments, where the key is mentioned(lines that start with #). The Key is case insensitive.
If the key is not set(disablepostprocessing and segmentstarttimeout), append key and value to the file. My function so far goes like this:
function setConfig( $file, $key, $value )
{
(Get-Content $file) |
Foreach-Object {$_ -replace "^"+$key+".=.+$", $key + " = " + $value } |
Set-Content $file
}
setConfig divider.conf "Logentrytimeout" "180"
setConfig divider.conf "disablepostprocessing" "1"
setConfig divider.conf "segmentstarttimeout" "180"
What is the correct regex?
How do I check if there was a replacement?
If there was no replacement: How can I append $key+" = "+$value to the file then?
Assuming the $key you want to replace is always at the beginning of a line, and that it contains no special regex characters
function setConfig( $file, $key, $value ) {
$content = Get-Content $file
if ( $content -match "^$key\s*=" ) {
$content -replace "^$key\s*=.*", "$key = $value" |
Set-Content $file
} else {
Add-Content $file "$key = $value"
}
}
setConfig "divider.conf" "Logentrytimeout" "180"
If there is no replacement $key = $value will be appended to the file.
Updated version of the functions above with some parametrisation and verbose output if required.
Function Set-FileConfigurationValue()
{
[CmdletBinding(PositionalBinding=$false)]
param(
[Parameter(Mandatory)][string][ValidateScript({Test-Path $_})] $Path,
[Parameter(Mandatory)][string][ValidateNotNullOrEmpty()] $Key,
[Parameter(Mandatory)][string][ValidateNotNullOrEmpty()] $Value,
[Switch] $ReplaceExistingValue,
[Switch] $ReplaceOnly
)
$content = Get-Content -Path $Path
$regreplace = $("(?<=$Key).*?=.*")
$regValue = $("=" + $Value)
if (([regex]::Match((Get-Content $Path),$regreplace)).success)
{
If ($ReplaceExistingValue)
{
Write-Verbose "Replacing configuration Key ""$Key"" in configuration file ""$Path"" with Value ""$Value"""
(Get-Content -Path $Path) | Foreach-Object { [regex]::Replace($_,$regreplace,$regvalue) } | Set-Content $Path
}
else
{
Write-Warning "Key ""$Key"" found in configuration file ""$Path"". To replace this Value specify parameter ""ReplaceExistingValue"""
}
}
elseif (-not $ReplaceOnly)
{
Write-Verbose "Adding configuration Key ""$Key"" to configuration file ""$Path"" using Value ""$Value"""
Add-Content -Path $Path -Value $("`n" + $Key + "=" + $Value)
}
else
{
Write-Warning "Key ""$Key"" not found in configuration file ""$Path"" and parameter ""ReplaceOnly"" has been specified therefore no work done"
}
}
I'd do this:
function setConfig( $file, $key, $value )
{
$regex = '^' + [regex]::escape($key) + '\s*=.+'
$replace = "$key = $value"
$old = get-content $file
$new = $old -replace $regex,$replace
if (compare-object $old $new)
{
Write-Host (compare-object $old $new | ft -auto | out-string) -ForegroundColor Yellow
$new | set-content $file
}
else {
$replace | add-content $file
Write-Host "$replace added to $file" -ForegroundColor Cyan
}
}
Edit: added a replacement bell, and a not match whistle.
Change the function to this:
function Set-Config( $file, $key, $value )
{
$regreplace = $("(?<=$key).*?=.*")
$regvalue = $(" = " + $value)
if (([regex]::Match((Get-Content $file),$regreplace)).success) {
(Get-Content $file) `
|Foreach-Object { [regex]::Replace($_,$regreplace,$regvalue)
} | Set-Content $file
} else {
Add-Content -Path $file -Value $("`n" + $key + " = " + $value)
}
}
Then when you call the function, use this format:
Set-Config -file "divider.conf" -key "Logentrytimeout" -value "180"
Edit: I forgot your requirement of adding the line if it doesn't exist. This will check for the $key, if it exists it will set its value to $value. If it doesn't exist it will add $key = $value to the end of the file. I also renamed the function to be more consistent with power shell naming conventions.
#CarlR Function it's for PowerShell Version 3. This it's the same adapted to PowerShell Version 2.
EDIT: Changed regular expression to fix two bugs on Set-FileConfigurationValue:
If you have one line like this:
; This is a Black line
And you try to do:
Set-FileConfigurationValue $configFile "Black" 20 -ReplaceExistingValue
You get one message about "Replacing" but nothing happens.
If you have two lines like these:
filesTmp=50
Tmp=50
And you try to do:
Set-FileConfigurationValue $configFile "Tmp" 20 -ReplaceExistingValue
You get the two lines changed!
filesTmp=20
Tmp=20
This is the final version:
Function Set-FileConfigurationValue()
{
[CmdletBinding()]
param(
[Parameter(Mandatory=$True)]
[ValidateScript({Test-Path $_})]
[string] $Path,
[Parameter(Mandatory=$True)]
[ValidateNotNullOrEmpty()]
[string] $Key,
[Parameter(Mandatory=$True)]
[ValidateNotNullOrEmpty()]
[string]$Value,
[Switch] $ReplaceExistingValue,
[Switch] $ReplaceOnly
)
$regmatch= $("^($Key\s*=\s*)(.*)")
$regreplace=$('${1}'+$Value)
if ((Get-Content $Path) -match $regmatch)
{
If ($ReplaceExistingValue)
{
Write-Verbose "Replacing configuration Key ""$Key"" in configuration file ""$Path"" with Value ""$Value"""
(Get-Content -Path $Path) | ForEach-Object { $_ -replace $regmatch,$regreplace } | Set-Content $Path
}
else
{
Write-Warning "Key ""$Key"" found in configuration file ""$Path"". To replace this Value specify parameter ""ReplaceExistingValue"""
}
}
elseif (-not $ReplaceOnly)
{
Write-Verbose "Adding configuration Key ""$Key"" to configuration file ""$Path"" using Value ""$Value"""
Add-Content -Path $Path -Value $("`n" + $Key + "=" + $Value)
}
else
{
Write-Warning "Key ""$Key"" not found in configuration file ""$Path"" and parameter ""ReplaceOnly"" has been specified therefore no work done"
}
}
I've also added a function to read from the config file
Function Get-FileConfigurationValue()
{
[CmdletBinding()]
param(
[Parameter(Mandatory=$True)]
[ValidateScript({Test-Path $_})]
[string] $Path,
[Parameter(Mandatory=$True)]
[ValidateNotNullOrEmpty()]
[string] $Key,
[Parameter(Mandatory=$False)]
[ValidateNotNullOrEmpty()]
[string]$Default=""
)
# Don't have spaces before key.
# To allow spaces, use "$Key\s*=\s*(.*)"
$regKey = $("^$Key\s*=\s*(.*)")
# Get only last time
$Value = Get-Content -Path $Path | Where {$_ -match $regKey} | Select-Object -last 1 | ForEach-Object { $matches[1] }
if(!$Value) { $Value=$Default }
Return $Value
}
function sed($filespec, $search, $replace)
{
foreach ($file in gci -Recurse $filespec | ? { Select-String $search $_ -Quiet } )
{
(gc $file) |
ForEach-Object {$_ -replace $search, $replace } |
Set-Content $file
}
}
Usage:
sed ".\*.config" "intranet-" "intranetsvcs-"