User Profile
Varun_Ghildiyal
Iron Contributor
Joined Mar 07, 2023
User Widgets
Recent Discussions
Re: JumpCloud
Regarding your question about the "Office365Id" parameter, this parameter refers to the Office 365 tenant ID. The tenant ID is a unique identifier for your Office 365 organization and can be found in the Azure Active Directory (Azure AD) portal. Once you have your Office 365 tenant ID, you can use it as the value for the "Office365Id" parameter in the "Get-JcSdkOffice365UsersToImport" command.762Views0likes0CommentsRe: Script to add an AD Security group to multiple User Home drive folders
Nitrox # Set the name of the AD security group to create $GroupName = "ADMigration" # Create the new AD security group New-ADGroup -Name $GroupName -GroupScope Global -GroupCategory Security # Set the list of home drive folders to modify $HomeDriveList = @( "\\server\share\user1", "\\server\share\user2", "\\server\share\user3" ) # Loop through each home drive folder and add the AD security group to its ACL with Read access foreach ($HomeDrive in $HomeDriveList) { # Get the current ACL of the home drive folder $acl = Get-Acl $HomeDrive # Create a new Access Rule for the AD security group with Read access $rule = New-Object System.Security.AccessControl.FileSystemAccessRule($GroupName, "ReadAndExecute", "Allow") # Add the new Access Rule to the home drive folder's ACL $acl.SetAccessRule($rule) # Set the modified ACL to the home drive folder Set-Acl $HomeDrive $acl } You will need to update the $GroupName and $HomeDriveList variables to match your environment. Also, make sure to run the script as an administrator and that the account you use has sufficient permissions to modify the ACLs of the home drive folders.9.2KViews0likes3CommentsRe: List SharePoint Sites, their Libraries, their folders, and their Permissions for Given User
xoxidein To achieve the desired output, you need to loop through each site collection, and for each site collection, you need to get all the document libraries and loop through each library to get the associated permissions. This script modification might help you. #Set Parameter $TenantSiteURL="https://contoso.sharepoint.com" #Connect to the Tenant site Connect-PnPOnline -Url $TenantSiteURL -Credentials (Get-Credential) #Get All Site collections - Exclude: Seach Center, Redirect site, Mysite Host, App Catalog, Content Type Hub, eDiscovery and Bot Sites $SiteCollections = Get-PnPTenantSite | Where -Property Template -NotIn ("SRCHCEN#0", "REDIRECTSITE#0", "SPSMSITEHOST#0", "APPCATALOG#0", "POINTPUBLISHINGHUB#0", "EDISC#0", "STS#-1") #Loop through each site collection ForEach($Site in $SiteCollections) { Write-Host "" Write-Host "Site: $($Site.Title)" #Get all document libraries $DocLibs = Get-PnPList -Web $Site.Url -Template "DocumentLibrary" #Loop through each library to get permissions ForEach($Lib in $DocLibs) { $Permissions = Get-PnPProperty -ClientObject $Lib -Property EffectiveBasePermissions #Loop through each permission level and output the library and permission ForEach($Perm in $Permissions) { $PermLevels = $Perm.FieldValues #Check if the user has any permission on the library If(($PermLevels.FullMask -band [Microsoft.SharePoint.Client.PermissionKind]::ViewListItems) -ne 0) { Write-Host "`t$($Lib.Title)`t`tRead" } If(($PermLevels.FullMask -band [Microsoft.SharePoint.Client.PermissionKind]::EditListItems) -ne 0) { Write-Host "`t$($Lib.Title)`t`tContribute" } If(($PermLevels.FullMask -band [Microsoft.SharePoint.Client.PermissionKind]::DeleteListItems) -ne 0) { Write-Host "`t$($Lib.Title)`t`tDelete" } If(($PermLevels.FullMask -band [Microsoft.SharePoint.Client.PermissionKind]::ManagePermissions) -ne 0) { Write-Host "`t$($Lib.Title)`t`tFull Control" } } } } This script loops through each site collection, gets all the document libraries, and then loops through each library to get the permissions. It then outputs the library name and associated permission level for each library that has any permission. You can modify this script to output the results to a CSV file or format it in any way you like.6.7KViews1like1CommentRe: Unable to print to pdf double copies (to a single file) using powershell
singhn83 The reason you're getting a blank file is because you're trying to print a PDF file using the Microsoft Print to PDF printer, but you haven't specified the printer driver to use. To fix this issue, you can install the Adobe PDF printer driver on your system and then use it to print the PDF file to multiple pages. Install the Adobe PDF printer driver by following the instructions on the Adobe website. Change the $printerName variable to "Adobe PDF" to use the Adobe PDF printer driver instead of the Microsoft Print to PDF printer driver. In the PrintDocument object, set the PrinterSettings.PrintToFile property to $false to print directly to the printer instead of to a file. Add the PrintPage event handler to the PrintDocument object to print the same page twice. # Load Assembly [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") # Adobe PDF printer $filePath = "C:\Users\Worksheets\Print Font Type\01-A\A\01-A.pdf" $printerName = "Adobe PDF" $numCopies = 2 # Create a PrinterSettings object and set the number of copies $printerSettings = New-Object System.Drawing.Printing.PrinterSettings $printerSettings.Copies = $numCopies # Create a PrintDocument object and set the file name and printer $printDoc = New-Object System.Drawing.Printing.PrintDocument $printDoc.DocumentName = $filePath $printDoc.PrinterSettings = $printerSettings # Set the printer to Adobe PDF $printDoc.PrinterSettings.PrinterName = $printerName # Disable printing to file $printDoc.PrinterSettings.PrintToFile = $false # Define the PrintPage event handler to print the same page twice $printDoc.add_PrintPage({ $page = $args[1] $args.Graphics.DrawImage($page, 0, 0, $page.Width, $page.Height) $args.HasMorePages = $true }) # Print the document $printDoc.Print() # Wait for the print job to complete Start-Sleep -Seconds 101.2KViews0likes2CommentsRe: Powershell Script when installing MSI and MSP together
It looks like there might be a typo in the script. In the line where you're trying to install the MSP file, you have the variable $file instead of $PSScriptRoot. Try changing this line: Start-Process $file -Wait -ArgumentList $patchArg to Start-Process "msiexec.exe" -Wait -ArgumentList $patchArg5.7KViews1like0CommentsRe: WSMANCONFIG
The values you provided, such as "Maxconcurrentusers," "maxshellruntime," "maxprocessespershell," "maxmemorypershell," and "Maxshellsperuser," are PowerShell session configuration settings that define limits for various aspects of PowerShell sessions. The default value of 2147483647 for these settings represents the maximum value of a 32-bit integer, which is the maximum value that can be stored in a 32-bit integer variable. In PowerShell version 5.1, these settings are defined in the session configuration file "Microsoft.PowerShell32.PSConsoleHost.psc1" or "Microsoft.PowerShellISE.PSConsoleHost.psc1" for 32-bit and 64-bit console hosts, respectively. It is possible that the default values for these settings were set to the maximum value to allow for maximum flexibility in configuring PowerShell sessions. However, it is also possible that these default values were set to the maximum value as a convenience for users, so that they do not have to specify a value for these settings unless they need to impose a specific limit. In any case, if you need to change any of these settings to impose a limit on a particular aspect of PowerShell sessions, you can do so by editing the appropriate session configuration file or by using the Set-PSSessionConfiguration cmdlet734Views0likes0CommentsRe: Parsing a file name and comparing a string to file creation date
Fred_Elmendorf To compare the date for every event*.pqd file in each folder, you can modify the existing foreach loop to loop through all the files instead of just the most recent file in each folder. Here's an updated version of the code with the necessary changes: $dirs = Get-ChildItem "\\fileshare\level1\level2\level3\parentdirectory" -Directory $csvLog = "\\fileshare\toplevel\myprofile\myfolders\Documents\PowerShellOutput\Ion Future Events.csv" foreach ($dir in $dirs) { $folder = $dir.Name $directory = $dir.FullName echo "Directory" $directory $files = Get-ChildItem $directory -Filter "event*.pqd" -Recurse $filesCount = $files.Count foreach ($file in $files) { $date_str = $file.Name.Substring(6, 8) echo "Date_str" $date_str $date_obj = [datetime]::ParseExact($date_str, "yyyyMMdd", $null) echo "Date Obj" $date_obj $creation_date = $file.CreationTime.Date echo "Creation Date" $creation_date if ($date_obj -gt $creation_date) { Write-Output "File $($file.Name) in folder $folder has date in the future." } else { $object = New-Object -TypeName psobject $object | Add-Member -MemberType NoteProperty -Name "Site" -Value $folder $object | Add-Member -MemberType NoteProperty -Name "File Name" -Value $file.Name $object | Add-Member -MemberType NoteProperty -Name "File Size" -Value $file.Length $object | Add-Member -MemberType NoteProperty -Name "Date Time" -Value $file.LastWriteTime $object | Add-Member -MemberType NoteProperty -Name "File Count" -Value $filesCount $object | Export-Csv $csvLog -Encoding ASCII -Append -NoTypeInformation } } } This code uses a nested foreach loop to loop through all the event*.pqd files in each folder. For each file, it extracts the date from the file name, converts it to a datetime object, and compares it to the file creation date. If the date in the file name is in the future, it writes a message to the console. Otherwise, it creates a new psobject with the relevant file information and exports it to the CSV file. the Export-Csv cmdlet is inside the inner loop, so it exports data for each file separately.3.8KViews0likes2CommentsRe: Export PrimarySmtpAddress
Pour séparer les informations des deux sociétés dans votre script, vous pouvez utiliser la propriété "PrimarySmtpAddress" des boîtes aux lettres pour déterminer à quelle société elles appartiennent. Pour cela, vous pouvez ajouter une condition IF qui vérifie si l'adresse SMTP de la boîte aux lettres contient le nom de domaine de la société 1 ou de la société 2. Ensuite, vous pouvez stocker les informations dans deux tableaux distincts. # Société 1 $mailboxesSociete1 = Get-Mailbox -ResultSize unlimited -Filter { PrimarySmtpAddress -like "*societe1.com" } | Select-Object UserPrincipalName foreach ($mailbox in $mailboxesSociete1) { $strMailbox = $mailbox.UserPrincipalName.ToString() $infoGetMailbox = Get-Mailbox $strMailbox $displayName = $infoGetMailbox.DisplayName $primarySmtpAddress = $infoGetMailbox.PrimarySmtpAddress $mailboxSize = Get-Mailbox $strMailbox | Get-MailboxStatistics | Select-Object TotalItemSize $mailboxSizeToString = $mailboxSize.TotalItemSize.ToString() $mailboxSizeBytes = $mailboxSizeToString.Split('\(\)')[1] [Double]$mailboxSizeBytesWithoutUnit = $mailboxSizeBytes.Split(' ')[0].Replace(',','') $mailboxSizeBytesWithoutUnitGb = $mailboxSizeBytesWithoutUnit/1024/1024/1024 $tabMailboxSizeSociete1 = [Array]$tabMailboxSizeSociete1 + [PSCustomObject] @{DisplayName = "$displayName"; Mailbox = "$primarySmtpAddress"; MailboxSizeGB = "$mailboxSizeBytesWithoutUnitGb"} } # Société 2 $mailboxesSociete2 = Get-Mailbox -ResultSize unlimited -Filter { PrimarySmtpAddress -like "*societe2.com" } | Select-Object UserPrincipalName foreach ($mailbox in $mailboxesSociete2) { $strMailbox = $mailbox.UserPrincipalName.ToString() $infoGetMailbox = Get-Mailbox $strMailbox $displayName = $infoGetMailbox.DisplayName $primarySmtpAddress = $infoGetMailbox.PrimarySmtpAddress $mailboxSize = Get-Mailbox $strMailbox | Get-MailboxStatistics | Select-Object TotalItemSize $mailboxSizeToString = $mailboxSize.TotalItemSize.ToString() $mailboxSizeBytes = $mailboxSizeToString.Split('\(\)')[1] [Double]$mailboxSizeBytesWithoutUnit = $mailboxSizeBytes.Split(' ')[0].Replace(',','') $mailboxSizeBytesWithoutUnitGb = $mailboxSizeBytesWithoutUnit/1024/1024/1024 $tabMailboxSizeSociete2 = [Array]$tabMailboxSizeSociete2 + [PSCustomObject] @{DisplayName = "$displayName"; Mailbox = "$primarySmtpAddress"; MailboxSizeGB = "$mailboxSizeBytesWithoutUnitGb"} } la condition IF dans les filtres de Get-Mailbox vérifie si l'adresse SMTP de la boîte aux lettres contient le nom de domaine de la société 1 ou de la société 2. Les résultats sont stockés dans les tableaux $mailboxesSociete1 et $mailboxesSociete2. Ensuite, chaque tableau est parcouru dans une boucle foreach, où les informations des794Views0likes4CommentsRe: Parsing a file name and comparing a string to file creation date
Based on your code, it seems that you're retrieving the creation date of the parent folder instead of the creation date of the file. To get the creation date of the file, you need to use the CreationTime property of the file object, which you already have stored in the $recentFile variable. Here's the modified code that retrieves the creation date of the file and compares it with the date in the file name: $dirs = Get-ChildItem "\\fileshare\level1\level2\level3\parentdirectory" -Directory $csvLog = "\\fileshare\toplevel\myprofile\myfolders\Documents\PowerShellOutput\Ion Future Events.csv" foreach ($dir in $dirs) { $recentFile = $null $folder = $dir.Name $directory = $dir.FullName echo "Directory" $directory $filesCount = (Get-ChildItem $directory -Filter "event*.pqd" -Recurse).Count $recentFile = Get-ChildItem $directory -Filter "event*.pqd" -Recurse | Sort-Object LastWriteTime -Descending| Select-Object -First 1 $recentFileName = $recentFile.Name $recentFileLength = $recentFile.Length $recentFileWriteTime = $recentFile.LastWriteTime if ($recentFile) { $date_str = $recentFileName.Substring(6, 8) echo "Date_str" $date_str $date_obj = [datetime]::ParseExact($date_str, "yyyyMMdd", $null) echo "Date Obj" $date_obj $creation_date = $recentFile.CreationTime.Date echo "Creation Date" $creation_date if ($date_obj -gt $creation_date) { Write-Output "Date in file name is in the future." } else { Write-Output "Date in file name is not in the future." } $object = New-Object -TypeName psobject $object | Add-Member -MemberType NoteProperty -Name "Site" -Value $folder $object | Add-Member -MemberType NoteProperty -Name "File Name" -Value $recentFileName $object | Add-Member -MemberType NoteProperty -Name "File Size" -Value $recentFileLength $object | Add-Member -MemberType NoteProperty -Name "Date Time" -Value $recentFileWriteTime $object | Add-Member -MemberType NoteProperty -Name "File Count" -Value $filesCount $object | Export-Csv $csvLog -Encoding ASCII -Append -NoTypeInformation } } With this modification, the code should now compare the date in the file name with the creation date of the file3.8KViews0likes4CommentsRe: Run Query and List Results operation
lParker755 if the query is returning duplicate values for the Incident Name, one possible solution is to add a "distinct" operator to the query to ensure that only unique values are returned SecurityIncidents | where IncidentNumber == '<Incident Number>' | distinct IncidentName | project IncidentName This query retrieves the unique IncidentName values for a given IncidentNumber. You can replace <Incident Number> with the actual incident number you want to query. If you still encounter duplicate values, you can add a "take" operator to the query to limit the results to a single row. Here's an example query that includes both "distinct" and "take" operators:1.1KViews0likes0CommentsRe: RE: How do you extract the UPN of a privileged user who has added a role via PIM?
JMSHW0420 If the query is showing the Service Principal of MS-PIM instead of the direct user initiating the 'add' action, you can try using the "InitiatedBy.servicePrincipalName" property to retrieve the service principal name of the PIM system. //Lookup the IdentityInfo table for any users holding a privileged role let privilegedusers= IdentityInfo | where TimeGenerated > ago(30d) | summarize arg_max(TimeGenerated, *) by AccountUPN | where isnotempty(AssignedRoles) | where AssignedRoles != "[]" | distinct AccountUPN; //Find actions taken by those users previously AuditLogs | where TimeGenerated between (ago(90d) ..now()) | where OperationName == "Add member to role" | extend UserPrincipalName = tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName) | extend UserAdded = tostring(parse_json(tostring(parse_json(tostring(TargetResources[0].userPrincipalName))))) | extend RoleAdded = tostring(parse_json(tostring(parse_json(tostring(TargetResources[0].modifiedProperties))[1].newValue))) | extend ServicePrincipalName = tostring(parse_json(tostring(InitiatedBy.servicePrincipalName))) | where isnotempty(UserPrincipalName) | where UserPrincipalName in (privilegedusers) | distinct TimeGenerated, UserPrincipalName, UserAdded, RoleAdded, ServicePrincipalName With this modification, the query should return the actual user who committed the 'add' action whenever possible. However, in some cases where the action is performed via PIM, the Service Principal of MS-PIM may still be shown instead of the actual user1.1KViews0likes0CommentsRe: Cohesity Integration with Sentinel
Check that the Cohesity_CL table is not being blocked. If the table is blocked, you may need to unblock it to allow data to flow. To do this, go to the Log Analytics workspace, select "Advanced Settings" and then select "Data" and ensure that the table is not blocked.1.1KViews1like1CommentRe: Subsequent alerts with different AlertName in Analytical Rule
drinrin search in (AuditLog_CL) | where AlertName == "Suspicious administrative activity" or AlertName == "Disabling of auditd logging" | extend TimeGeneratedUtc = TimeGenerated + 1h | join kind=inner ( search in (AuditLog_CL) | where AlertName == "Disabling of auditd logging" or AlertName == "Suspicious administrative activity" ) on Computer, Account, TimeGeneratedUtc | where TimeGeneratedUtc1 < TimeGeneratedUtc | where TimeGeneratedUtc <= TimeGeneratedUtc1 + 1h This query looks for events with the AlertName "Suspicious administrative activity" or "Disabling of auditd logging" and joins them on the fields "Computer", "Account", and "TimeGeneratedUtc". It then filters for events where the time difference between the two events is less than 1 hour.850Views0likes0CommentsRe: Restricting PowerShell folder search to a specific date range
Fred_Elmendorf No problem! You can modify the script to count only the files that were created in 2023. Here's how you can do it: $dirs = Get-ChildItem "\\Myorg\firstlevel\secondlevel\thirdlevel\Ion" -Directory $csvLog = "\\Myorg\output\fileshare\mystuff\Documents\PowerShellOutput\Latest Ion Trend Files Size Counts.csv" $startDate = Get-Date "01/01/2023" $endDate = Get-Date "01/01/2024" foreach ($dir in $dirs) { $folder = $dir.Name $directory = $dir.FullName $filesCount = (Get-ChildItem $directory -Filter "trend*.pqd" -Recurse ` | Where-Object { $_.CreationTime -ge $startDate -and $_.CreationTime -lt $endDate }).Count $object = New-Object -TypeName psobject $object | Add-Member -MemberType NoteProperty -Name "Site" -Value $folder $object | Add-Member -MemberType NoteProperty -Name "File Count" -Value $filesCount $object | Export-Csv $csvLog -Encoding ASCII -Append -NoTypeInformation } In the modified script, we are still iterating through the directories, but instead of counting and outputting the latest file, we are counting the number of files that were created in 2023. We achieve this by filtering the files based on their CreationTime property and checking if it falls within the startDate and endDate range. We then create a PowerShell object and add the Site name and the File Count for that directory, and then export it to a CSV file. Let me know if this solves your problem.7.9KViews1like1Comment
Recent Blog Articles
No content to show