"}},"componentScriptGroups({\"componentId\":\"custom.widget.MicrosoftFooter\"})":{"__typename":"ComponentScriptGroups","scriptGroups":{"__typename":"ComponentScriptGroupsDefinition","afterInteractive":{"__typename":"PageScriptGroupDefinition","group":"AFTER_INTERACTIVE","scriptIds":[]},"lazyOnLoad":{"__typename":"PageScriptGroupDefinition","group":"LAZY_ON_LOAD","scriptIds":[]}},"componentScripts":[]},"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"components/community/NavbarDropdownToggle\"]})":[{"__ref":"CachedAsset:text:en_US-components/community/NavbarDropdownToggle-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageListTabs\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageListTabs-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageView/MessageViewInline\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageView/MessageViewInline-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/common/OverflowNav\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/common/OverflowNav-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"components/users/UserLink\"]})":[{"__ref":"CachedAsset:text:en_US-components/users/UserLink-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageSubject\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageSubject-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageTime\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageTime-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/nodes/NodeIcon\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/nodes/NodeIcon-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageUnreadCount\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageUnreadCount-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageViewCount\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageViewCount-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"components/kudos/KudosCount\"]})":[{"__ref":"CachedAsset:text:en_US-components/kudos/KudosCount-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageRepliesCount\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageRepliesCount-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/users/UserAvatar\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/users/UserAvatar-1745505307000"}]},"Theme:customTheme1":{"__typename":"Theme","id":"customTheme1"},"User:user:-1":{"__typename":"User","id":"user:-1","uid":-1,"login":"Deleted","email":"","avatar":null,"rank":null,"kudosWeight":1,"registrationData":{"__typename":"RegistrationData","status":"ANONYMOUS","registrationTime":null,"confirmEmailStatus":false,"registrationAccessLevel":"VIEW","ssoRegistrationFields":[]},"ssoId":null,"profileSettings":{"__typename":"ProfileSettings","dateDisplayStyle":{"__typename":"InheritableStringSettingWithPossibleValues","key":"layout.friendly_dates_enabled","value":"false","localValue":"true","possibleValues":["true","false"]},"dateDisplayFormat":{"__typename":"InheritableStringSetting","key":"layout.format_pattern_date","value":"MMM dd yyyy","localValue":"MM-dd-yyyy"},"language":{"__typename":"InheritableStringSettingWithPossibleValues","key":"profile.language","value":"en-US","localValue":null,"possibleValues":["en-US","es-ES"]},"repliesSortOrder":{"__typename":"InheritableStringSettingWithPossibleValues","key":"config.user_replies_sort_order","value":"DEFAULT","localValue":"DEFAULT","possibleValues":["DEFAULT","LIKES","PUBLISH_TIME","REVERSE_PUBLISH_TIME"]}},"deleted":false},"CachedAsset:pages-1746563621366":{"__typename":"CachedAsset","id":"pages-1746563621366","value":[{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"BlogViewAllPostsPage","type":"BLOG","urlPath":"/category/:categoryId/blog/:boardId/all-posts/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"CasePortalPage","type":"CASE_PORTAL","urlPath":"/caseportal","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"CreateGroupHubPage","type":"GROUP_HUB","urlPath":"/groups/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"CaseViewPage","type":"CASE_DETAILS","urlPath":"/case/:caseId/:caseNumber","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"InboxPage","type":"COMMUNITY","urlPath":"/inbox","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"HelpFAQPage","type":"COMMUNITY","urlPath":"/help","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"IdeaMessagePage","type":"IDEA_POST","urlPath":"/idea/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"IdeaViewAllIdeasPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId/all-ideas/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"LoginPage","type":"USER","urlPath":"/signin","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"BlogPostPage","type":"BLOG","urlPath":"/category/:categoryId/blogs/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"UserBlogPermissions.Page","type":"COMMUNITY","urlPath":"/c/user-blog-permissions/page","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"ThemeEditorPage","type":"COMMUNITY","urlPath":"/designer/themes","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"TkbViewAllArticlesPage","type":"TKB","urlPath":"/category/:categoryId/kb/:boardId/all-articles/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1730819800000,"localOverride":null,"page":{"id":"AllEvents","type":"CUSTOM","urlPath":"/Events","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"OccasionEditPage","type":"EVENT","urlPath":"/event/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"OAuthAuthorizationAllowPage","type":"USER","urlPath":"/auth/authorize/allow","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"PageEditorPage","type":"COMMUNITY","urlPath":"/designer/pages","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"PostPage","type":"COMMUNITY","urlPath":"/category/:categoryId/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"ForumBoardPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"TkbBoardPage","type":"TKB","urlPath":"/category/:categoryId/kb/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"EventPostPage","type":"EVENT","urlPath":"/category/:categoryId/events/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"UserBadgesPage","type":"COMMUNITY","urlPath":"/users/:login/:userId/badges","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"GroupHubMembershipAction","type":"GROUP_HUB","urlPath":"/membership/join/:nodeId/:membershipType","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"MaintenancePage","type":"COMMUNITY","urlPath":"/maintenance","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"IdeaReplyPage","type":"IDEA_REPLY","urlPath":"/idea/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"UserSettingsPage","type":"USER","urlPath":"/mysettings/:userSettingsTab","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"GroupHubsPage","type":"GROUP_HUB","urlPath":"/groups","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"ForumPostPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"OccasionRsvpActionPage","type":"OCCASION","urlPath":"/event/:boardId/:messageSubject/:messageId/rsvp/:responseType","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"VerifyUserEmailPage","type":"USER","urlPath":"/verifyemail/:userId/:verifyEmailToken","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"AllOccasionsPage","type":"OCCASION","urlPath":"/category/:categoryId/events/:boardId/all-events/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"EventBoardPage","type":"EVENT","urlPath":"/category/:categoryId/events/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"TkbReplyPage","type":"TKB_REPLY","urlPath":"/kb/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"IdeaBoardPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"CommunityGuideLinesPage","type":"COMMUNITY","urlPath":"/communityguidelines","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"CaseCreatePage","type":"SALESFORCE_CASE_CREATION","urlPath":"/caseportal/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"TkbEditPage","type":"TKB","urlPath":"/kb/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"ForgotPasswordPage","type":"USER","urlPath":"/forgotpassword","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"IdeaEditPage","type":"IDEA","urlPath":"/idea/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"TagPage","type":"COMMUNITY","urlPath":"/tag/:tagName","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"BlogBoardPage","type":"BLOG","urlPath":"/category/:categoryId/blog/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"OccasionMessagePage","type":"OCCASION_TOPIC","urlPath":"/event/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"ManageContentPage","type":"COMMUNITY","urlPath":"/managecontent","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"ClosedMembershipNodeNonMembersPage","type":"GROUP_HUB","urlPath":"/closedgroup/:groupHubId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"CommunityPage","type":"COMMUNITY","urlPath":"/","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"ForumMessagePage","type":"FORUM_TOPIC","urlPath":"/discussions/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"IdeaPostPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1730819800000,"localOverride":null,"page":{"id":"CommunityHub.Page","type":"CUSTOM","urlPath":"/Directory","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"BlogMessagePage","type":"BLOG_ARTICLE","urlPath":"/blog/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"RegistrationPage","type":"USER","urlPath":"/register","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"EditGroupHubPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"ForumEditPage","type":"FORUM","urlPath":"/discussions/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"ResetPasswordPage","type":"USER","urlPath":"/resetpassword/:userId/:resetPasswordToken","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1730819800000,"localOverride":null,"page":{"id":"AllBlogs.Page","type":"CUSTOM","urlPath":"/blogs","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"TkbMessagePage","type":"TKB_ARTICLE","urlPath":"/kb/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"BlogEditPage","type":"BLOG","urlPath":"/blog/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"ManageUsersPage","type":"USER","urlPath":"/users/manage/:tab?/:manageUsersTab?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"ForumReplyPage","type":"FORUM_REPLY","urlPath":"/discussions/:boardId/:messageSubject/:messageId/replies/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"PrivacyPolicyPage","type":"COMMUNITY","urlPath":"/privacypolicy","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"NotificationPage","type":"COMMUNITY","urlPath":"/notifications","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"UserPage","type":"USER","urlPath":"/users/:login/:userId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"HealthCheckPage","type":"COMMUNITY","urlPath":"/health","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"OccasionReplyPage","type":"OCCASION_REPLY","urlPath":"/event/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"ManageMembersPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/manage/:tab?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"SearchResultsPage","type":"COMMUNITY","urlPath":"/search","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"BlogReplyPage","type":"BLOG_REPLY","urlPath":"/blog/:boardId/:messageSubject/:messageId/replies/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"GroupHubPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"TermsOfServicePage","type":"COMMUNITY","urlPath":"/termsofservice","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"CategoryPage","type":"CATEGORY","urlPath":"/category/:categoryId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"ForumViewAllTopicsPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId/all-topics/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"TkbPostPage","type":"TKB","urlPath":"/category/:categoryId/kbs/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746563621366,"localOverride":null,"page":{"id":"GroupHubPostPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"}],"localOverride":false},"CachedAsset:text:en_US-components/context/AppContext/AppContextProvider-0":{"__typename":"CachedAsset","id":"text:en_US-components/context/AppContext/AppContextProvider-0","value":{"noCommunity":"Cannot find community","noUser":"Cannot find current user","noNode":"Cannot find node with id {nodeId}","noMessage":"Cannot find message with id {messageId}","userBanned":"We're sorry, but you have been banned from using this site.","userBannedReason":"You have been banned for the following reason: {reason}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Loading/LoadingDot-0":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Loading/LoadingDot-0","value":{"title":"Loading..."},"localOverride":false},"CachedAsset:theme:customTheme1-1746563620816":{"__typename":"CachedAsset","id":"theme:customTheme1-1746563620816","value":{"id":"customTheme1","animation":{"fast":"150ms","normal":"250ms","slow":"500ms","slowest":"750ms","function":"cubic-bezier(0.07, 0.91, 0.51, 1)","__typename":"AnimationThemeSettings"},"avatar":{"borderRadius":"50%","collections":["default"],"__typename":"AvatarThemeSettings"},"basics":{"browserIcon":{"imageAssetName":"favicon-1730836283320.png","imageLastModified":"1730836286415","__typename":"ThemeAsset"},"customerLogo":{"imageAssetName":"favicon-1730836271365.png","imageLastModified":"1730836274203","__typename":"ThemeAsset"},"maximumWidthOfPageContent":"1300px","oneColumnNarrowWidth":"800px","gridGutterWidthMd":"30px","gridGutterWidthXs":"10px","pageWidthStyle":"WIDTH_OF_BROWSER","__typename":"BasicsThemeSettings"},"buttons":{"borderRadiusSm":"3px","borderRadius":"3px","borderRadiusLg":"5px","paddingY":"5px","paddingYLg":"7px","paddingYHero":"var(--lia-bs-btn-padding-y-lg)","paddingX":"12px","paddingXLg":"16px","paddingXHero":"60px","fontStyle":"NORMAL","fontWeight":"700","textTransform":"NONE","disabledOpacity":0.5,"primaryTextColor":"var(--lia-bs-white)","primaryTextHoverColor":"var(--lia-bs-white)","primaryTextActiveColor":"var(--lia-bs-white)","primaryBgColor":"var(--lia-bs-primary)","primaryBgHoverColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) * 0.85))","primaryBgActiveColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) * 0.7))","primaryBorder":"1px solid transparent","primaryBorderHover":"1px solid transparent","primaryBorderActive":"1px solid transparent","primaryBorderFocus":"1px solid var(--lia-bs-white)","primaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","secondaryTextColor":"var(--lia-bs-gray-900)","secondaryTextHoverColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.95))","secondaryTextActiveColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.9))","secondaryBgColor":"var(--lia-bs-gray-200)","secondaryBgHoverColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.96))","secondaryBgActiveColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.92))","secondaryBorder":"1px solid transparent","secondaryBorderHover":"1px solid transparent","secondaryBorderActive":"1px solid transparent","secondaryBorderFocus":"1px solid transparent","secondaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","tertiaryTextColor":"var(--lia-bs-gray-900)","tertiaryTextHoverColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.95))","tertiaryTextActiveColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.9))","tertiaryBgColor":"transparent","tertiaryBgHoverColor":"transparent","tertiaryBgActiveColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.04)","tertiaryBorder":"1px solid transparent","tertiaryBorderHover":"1px solid hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","tertiaryBorderActive":"1px solid transparent","tertiaryBorderFocus":"1px solid transparent","tertiaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","destructiveTextColor":"var(--lia-bs-danger)","destructiveTextHoverColor":"hsl(var(--lia-bs-danger-h), var(--lia-bs-danger-s), calc(var(--lia-bs-danger-l) * 0.95))","destructiveTextActiveColor":"hsl(var(--lia-bs-danger-h), var(--lia-bs-danger-s), calc(var(--lia-bs-danger-l) * 0.9))","destructiveBgColor":"var(--lia-bs-gray-200)","destructiveBgHoverColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.96))","destructiveBgActiveColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.92))","destructiveBorder":"1px solid transparent","destructiveBorderHover":"1px solid transparent","destructiveBorderActive":"1px solid transparent","destructiveBorderFocus":"1px solid transparent","destructiveBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","__typename":"ButtonsThemeSettings"},"border":{"color":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","mainContent":"NONE","sideContent":"LIGHT","radiusSm":"3px","radius":"5px","radiusLg":"9px","radius50":"100vw","__typename":"BorderThemeSettings"},"boxShadow":{"xs":"0 0 0 1px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.08), 0 3px 0 -1px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.16)","sm":"0 2px 4px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.12)","md":"0 5px 15px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.3)","lg":"0 10px 30px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.3)","__typename":"BoxShadowThemeSettings"},"cards":{"bgColor":"var(--lia-panel-bg-color)","borderRadius":"var(--lia-panel-border-radius)","boxShadow":"var(--lia-box-shadow-xs)","__typename":"CardsThemeSettings"},"chip":{"maxWidth":"300px","height":"30px","__typename":"ChipThemeSettings"},"coreTypes":{"defaultMessageLinkColor":"var(--lia-bs-link-color)","defaultMessageLinkDecoration":"none","defaultMessageLinkFontStyle":"NORMAL","defaultMessageLinkFontWeight":"400","defaultMessageFontStyle":"NORMAL","defaultMessageFontWeight":"400","defaultMessageFontFamily":"var(--lia-bs-font-family-base)","forumColor":"#4099E2","forumFontFamily":"var(--lia-bs-font-family-base)","forumFontWeight":"var(--lia-default-message-font-weight)","forumLineHeight":"var(--lia-bs-line-height-base)","forumFontStyle":"var(--lia-default-message-font-style)","forumMessageLinkColor":"var(--lia-default-message-link-color)","forumMessageLinkDecoration":"var(--lia-default-message-link-decoration)","forumMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","forumMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","forumSolvedColor":"#148563","blogColor":"#1CBAA0","blogFontFamily":"var(--lia-bs-font-family-base)","blogFontWeight":"var(--lia-default-message-font-weight)","blogLineHeight":"1.75","blogFontStyle":"var(--lia-default-message-font-style)","blogMessageLinkColor":"var(--lia-default-message-link-color)","blogMessageLinkDecoration":"var(--lia-default-message-link-decoration)","blogMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","blogMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","tkbColor":"#4C6B90","tkbFontFamily":"var(--lia-bs-font-family-base)","tkbFontWeight":"var(--lia-default-message-font-weight)","tkbLineHeight":"1.75","tkbFontStyle":"var(--lia-default-message-font-style)","tkbMessageLinkColor":"var(--lia-default-message-link-color)","tkbMessageLinkDecoration":"var(--lia-default-message-link-decoration)","tkbMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","tkbMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","qandaColor":"#4099E2","qandaFontFamily":"var(--lia-bs-font-family-base)","qandaFontWeight":"var(--lia-default-message-font-weight)","qandaLineHeight":"var(--lia-bs-line-height-base)","qandaFontStyle":"var(--lia-default-message-link-font-style)","qandaMessageLinkColor":"var(--lia-default-message-link-color)","qandaMessageLinkDecoration":"var(--lia-default-message-link-decoration)","qandaMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","qandaMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","qandaSolvedColor":"#3FA023","ideaColor":"#FF8000","ideaFontFamily":"var(--lia-bs-font-family-base)","ideaFontWeight":"var(--lia-default-message-font-weight)","ideaLineHeight":"var(--lia-bs-line-height-base)","ideaFontStyle":"var(--lia-default-message-font-style)","ideaMessageLinkColor":"var(--lia-default-message-link-color)","ideaMessageLinkDecoration":"var(--lia-default-message-link-decoration)","ideaMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","ideaMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","contestColor":"#FCC845","contestFontFamily":"var(--lia-bs-font-family-base)","contestFontWeight":"var(--lia-default-message-font-weight)","contestLineHeight":"var(--lia-bs-line-height-base)","contestFontStyle":"var(--lia-default-message-link-font-style)","contestMessageLinkColor":"var(--lia-default-message-link-color)","contestMessageLinkDecoration":"var(--lia-default-message-link-decoration)","contestMessageLinkFontStyle":"ITALIC","contestMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","occasionColor":"#D13A1F","occasionFontFamily":"var(--lia-bs-font-family-base)","occasionFontWeight":"var(--lia-default-message-font-weight)","occasionLineHeight":"var(--lia-bs-line-height-base)","occasionFontStyle":"var(--lia-default-message-font-style)","occasionMessageLinkColor":"var(--lia-default-message-link-color)","occasionMessageLinkDecoration":"var(--lia-default-message-link-decoration)","occasionMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","occasionMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","grouphubColor":"#333333","categoryColor":"#949494","communityColor":"#FFFFFF","productColor":"#949494","__typename":"CoreTypesThemeSettings"},"colors":{"black":"#000000","white":"#FFFFFF","gray100":"#F7F7F7","gray200":"#F7F7F7","gray300":"#E8E8E8","gray400":"#D9D9D9","gray500":"#CCCCCC","gray600":"#717171","gray700":"#707070","gray800":"#545454","gray900":"#333333","dark":"#545454","light":"#F7F7F7","primary":"#0069D4","secondary":"#333333","bodyText":"#1E1E1E","bodyBg":"#FFFFFF","info":"#409AE2","success":"#41C5AE","warning":"#FCC844","danger":"#BC341B","alertSystem":"#FF6600","textMuted":"#707070","highlight":"#FFFCAD","outline":"var(--lia-bs-primary)","custom":["#D3F5A4","#243A5E"],"__typename":"ColorsThemeSettings"},"divider":{"size":"3px","marginLeft":"4px","marginRight":"4px","borderRadius":"50%","bgColor":"var(--lia-bs-gray-600)","bgColorActive":"var(--lia-bs-gray-600)","__typename":"DividerThemeSettings"},"dropdown":{"fontSize":"var(--lia-bs-font-size-sm)","borderColor":"var(--lia-bs-border-color)","borderRadius":"var(--lia-bs-border-radius-sm)","dividerBg":"var(--lia-bs-gray-300)","itemPaddingY":"5px","itemPaddingX":"20px","headerColor":"var(--lia-bs-gray-700)","__typename":"DropdownThemeSettings"},"email":{"link":{"color":"#0069D4","hoverColor":"#0061c2","decoration":"none","hoverDecoration":"underline","__typename":"EmailLinkSettings"},"border":{"color":"#e4e4e4","__typename":"EmailBorderSettings"},"buttons":{"borderRadiusLg":"5px","paddingXLg":"16px","paddingYLg":"7px","fontWeight":"700","primaryTextColor":"#ffffff","primaryTextHoverColor":"#ffffff","primaryBgColor":"#0069D4","primaryBgHoverColor":"#005cb8","primaryBorder":"1px solid transparent","primaryBorderHover":"1px solid transparent","__typename":"EmailButtonsSettings"},"panel":{"borderRadius":"5px","borderColor":"#e4e4e4","__typename":"EmailPanelSettings"},"__typename":"EmailThemeSettings"},"emoji":{"skinToneDefault":"#ffcd43","skinToneLight":"#fae3c5","skinToneMediumLight":"#e2cfa5","skinToneMedium":"#daa478","skinToneMediumDark":"#a78058","skinToneDark":"#5e4d43","__typename":"EmojiThemeSettings"},"heading":{"color":"var(--lia-bs-body-color)","fontFamily":"Segoe UI","fontStyle":"NORMAL","fontWeight":"400","h1FontSize":"34px","h2FontSize":"32px","h3FontSize":"28px","h4FontSize":"24px","h5FontSize":"20px","h6FontSize":"16px","lineHeight":"1.3","subHeaderFontSize":"11px","subHeaderFontWeight":"500","h1LetterSpacing":"normal","h2LetterSpacing":"normal","h3LetterSpacing":"normal","h4LetterSpacing":"normal","h5LetterSpacing":"normal","h6LetterSpacing":"normal","subHeaderLetterSpacing":"2px","h1FontWeight":"var(--lia-bs-headings-font-weight)","h2FontWeight":"var(--lia-bs-headings-font-weight)","h3FontWeight":"var(--lia-bs-headings-font-weight)","h4FontWeight":"var(--lia-bs-headings-font-weight)","h5FontWeight":"var(--lia-bs-headings-font-weight)","h6FontWeight":"var(--lia-bs-headings-font-weight)","__typename":"HeadingThemeSettings"},"icons":{"size10":"10px","size12":"12px","size14":"14px","size16":"16px","size20":"20px","size24":"24px","size30":"30px","size40":"40px","size50":"50px","size60":"60px","size80":"80px","size120":"120px","size160":"160px","__typename":"IconsThemeSettings"},"imagePreview":{"bgColor":"var(--lia-bs-gray-900)","titleColor":"var(--lia-bs-white)","controlColor":"var(--lia-bs-white)","controlBgColor":"var(--lia-bs-gray-800)","__typename":"ImagePreviewThemeSettings"},"input":{"borderColor":"var(--lia-bs-gray-600)","disabledColor":"var(--lia-bs-gray-600)","focusBorderColor":"var(--lia-bs-primary)","labelMarginBottom":"10px","btnFontSize":"var(--lia-bs-font-size-sm)","focusBoxShadow":"0 0 0 3px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","checkLabelMarginBottom":"2px","checkboxBorderRadius":"3px","borderRadiusSm":"var(--lia-bs-border-radius-sm)","borderRadius":"var(--lia-bs-border-radius)","borderRadiusLg":"var(--lia-bs-border-radius-lg)","formTextMarginTop":"4px","textAreaBorderRadius":"var(--lia-bs-border-radius)","activeFillColor":"var(--lia-bs-primary)","__typename":"InputThemeSettings"},"loading":{"dotDarkColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.2)","dotLightColor":"hsla(var(--lia-bs-white-h), var(--lia-bs-white-s), var(--lia-bs-white-l), 0.5)","barDarkColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.06)","barLightColor":"hsla(var(--lia-bs-white-h), var(--lia-bs-white-s), var(--lia-bs-white-l), 0.4)","__typename":"LoadingThemeSettings"},"link":{"color":"var(--lia-bs-primary)","hoverColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) - 10%))","decoration":"none","hoverDecoration":"underline","__typename":"LinkThemeSettings"},"listGroup":{"itemPaddingY":"15px","itemPaddingX":"15px","borderColor":"var(--lia-bs-gray-300)","__typename":"ListGroupThemeSettings"},"modal":{"contentTextColor":"var(--lia-bs-body-color)","contentBg":"var(--lia-bs-white)","backgroundBg":"var(--lia-bs-black)","smSize":"440px","mdSize":"760px","lgSize":"1080px","backdropOpacity":0.3,"contentBoxShadowXs":"var(--lia-bs-box-shadow-sm)","contentBoxShadow":"var(--lia-bs-box-shadow)","headerFontWeight":"700","__typename":"ModalThemeSettings"},"navbar":{"position":"FIXED","background":{"attachment":null,"clip":null,"color":"var(--lia-bs-white)","imageAssetName":"","imageLastModified":"0","origin":null,"position":"CENTER_CENTER","repeat":"NO_REPEAT","size":"COVER","__typename":"BackgroundProps"},"backgroundOpacity":0.8,"paddingTop":"15px","paddingBottom":"15px","borderBottom":"1px solid var(--lia-bs-border-color)","boxShadow":"var(--lia-bs-box-shadow-sm)","brandMarginRight":"30px","brandMarginRightSm":"10px","brandLogoHeight":"30px","linkGap":"10px","linkJustifyContent":"flex-start","linkPaddingY":"5px","linkPaddingX":"10px","linkDropdownPaddingY":"9px","linkDropdownPaddingX":"var(--lia-nav-link-px)","linkColor":"var(--lia-bs-body-color)","linkHoverColor":"var(--lia-bs-primary)","linkFontSize":"var(--lia-bs-font-size-sm)","linkFontStyle":"NORMAL","linkFontWeight":"400","linkTextTransform":"NONE","linkLetterSpacing":"normal","linkBorderRadius":"var(--lia-bs-border-radius-sm)","linkBgColor":"transparent","linkBgHoverColor":"transparent","linkBorder":"none","linkBorderHover":"none","linkBoxShadow":"none","linkBoxShadowHover":"none","linkTextBorderBottom":"none","linkTextBorderBottomHover":"none","dropdownPaddingTop":"10px","dropdownPaddingBottom":"15px","dropdownPaddingX":"10px","dropdownMenuOffset":"2px","dropdownDividerMarginTop":"10px","dropdownDividerMarginBottom":"10px","dropdownBorderColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","controllerBgHoverColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.1)","controllerIconColor":"var(--lia-bs-body-color)","controllerIconHoverColor":"var(--lia-bs-body-color)","controllerTextColor":"var(--lia-nav-controller-icon-color)","controllerTextHoverColor":"var(--lia-nav-controller-icon-hover-color)","controllerHighlightColor":"hsla(30, 100%, 50%)","controllerHighlightTextColor":"var(--lia-yiq-light)","controllerBorderRadius":"var(--lia-border-radius-50)","hamburgerColor":"var(--lia-nav-controller-icon-color)","hamburgerHoverColor":"var(--lia-nav-controller-icon-color)","hamburgerBgColor":"transparent","hamburgerBgHoverColor":"transparent","hamburgerBorder":"none","hamburgerBorderHover":"none","collapseMenuMarginLeft":"20px","collapseMenuDividerBg":"var(--lia-nav-link-color)","collapseMenuDividerOpacity":0.16,"__typename":"NavbarThemeSettings"},"pager":{"textColor":"var(--lia-bs-link-color)","textFontWeight":"var(--lia-font-weight-md)","textFontSize":"var(--lia-bs-font-size-sm)","__typename":"PagerThemeSettings"},"panel":{"bgColor":"var(--lia-bs-white)","borderRadius":"var(--lia-bs-border-radius)","borderColor":"var(--lia-bs-border-color)","boxShadow":"none","__typename":"PanelThemeSettings"},"popover":{"arrowHeight":"8px","arrowWidth":"16px","maxWidth":"300px","minWidth":"100px","headerBg":"var(--lia-bs-white)","borderColor":"var(--lia-bs-border-color)","borderRadius":"var(--lia-bs-border-radius)","boxShadow":"0 0.5rem 1rem hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.15)","__typename":"PopoverThemeSettings"},"prism":{"color":"#000000","bgColor":"#f5f2f0","fontFamily":"var(--font-family-monospace)","fontSize":"var(--lia-bs-font-size-base)","fontWeightBold":"var(--lia-bs-font-weight-bold)","fontStyleItalic":"italic","tabSize":2,"highlightColor":"#b3d4fc","commentColor":"#62707e","punctuationColor":"#6f6f6f","namespaceOpacity":"0.7","propColor":"#990055","selectorColor":"#517a00","operatorColor":"#906736","operatorBgColor":"hsla(0, 0%, 100%, 0.5)","keywordColor":"#0076a9","functionColor":"#d3284b","variableColor":"#c14700","__typename":"PrismThemeSettings"},"rte":{"bgColor":"var(--lia-bs-white)","borderRadius":"var(--lia-panel-border-radius)","boxShadow":" var(--lia-panel-box-shadow)","customColor1":"#bfedd2","customColor2":"#fbeeb8","customColor3":"#f8cac6","customColor4":"#eccafa","customColor5":"#c2e0f4","customColor6":"#2dc26b","customColor7":"#f1c40f","customColor8":"#e03e2d","customColor9":"#b96ad9","customColor10":"#3598db","customColor11":"#169179","customColor12":"#e67e23","customColor13":"#ba372a","customColor14":"#843fa1","customColor15":"#236fa1","customColor16":"#ecf0f1","customColor17":"#ced4d9","customColor18":"#95a5a6","customColor19":"#7e8c8d","customColor20":"#34495e","customColor21":"#000000","customColor22":"#ffffff","defaultMessageHeaderMarginTop":"40px","defaultMessageHeaderMarginBottom":"20px","defaultMessageItemMarginTop":"0","defaultMessageItemMarginBottom":"10px","diffAddedColor":"hsla(170, 53%, 51%, 0.4)","diffChangedColor":"hsla(43, 97%, 63%, 0.4)","diffNoneColor":"hsla(0, 0%, 80%, 0.4)","diffRemovedColor":"hsla(9, 74%, 47%, 0.4)","specialMessageHeaderMarginTop":"40px","specialMessageHeaderMarginBottom":"20px","specialMessageItemMarginTop":"0","specialMessageItemMarginBottom":"10px","__typename":"RteThemeSettings"},"tags":{"bgColor":"var(--lia-bs-gray-200)","bgHoverColor":"var(--lia-bs-gray-400)","borderRadius":"var(--lia-bs-border-radius-sm)","color":"var(--lia-bs-body-color)","hoverColor":"var(--lia-bs-body-color)","fontWeight":"var(--lia-font-weight-md)","fontSize":"var(--lia-font-size-xxs)","textTransform":"UPPERCASE","letterSpacing":"0.5px","__typename":"TagsThemeSettings"},"toasts":{"borderRadius":"var(--lia-bs-border-radius)","paddingX":"12px","__typename":"ToastsThemeSettings"},"typography":{"fontFamilyBase":"Segoe UI","fontStyleBase":"NORMAL","fontWeightBase":"400","fontWeightLight":"300","fontWeightNormal":"400","fontWeightMd":"500","fontWeightBold":"700","letterSpacingSm":"normal","letterSpacingXs":"normal","lineHeightBase":"1.5","fontSizeBase":"16px","fontSizeXxs":"11px","fontSizeXs":"12px","fontSizeSm":"14px","fontSizeLg":"20px","fontSizeXl":"24px","smallFontSize":"14px","customFonts":[{"source":"SERVER","name":"Segoe UI","styles":[{"style":"NORMAL","weight":"400","__typename":"FontStyleData"},{"style":"NORMAL","weight":"300","__typename":"FontStyleData"},{"style":"NORMAL","weight":"600","__typename":"FontStyleData"},{"style":"NORMAL","weight":"700","__typename":"FontStyleData"},{"style":"ITALIC","weight":"400","__typename":"FontStyleData"}],"assetNames":["SegoeUI-normal-400.woff2","SegoeUI-normal-300.woff2","SegoeUI-normal-600.woff2","SegoeUI-normal-700.woff2","SegoeUI-italic-400.woff2"],"__typename":"CustomFont"},{"source":"SERVER","name":"MWF Fluent Icons","styles":[{"style":"NORMAL","weight":"400","__typename":"FontStyleData"}],"assetNames":["MWFFluentIcons-normal-400.woff2"],"__typename":"CustomFont"}],"__typename":"TypographyThemeSettings"},"unstyledListItem":{"marginBottomSm":"5px","marginBottomMd":"10px","marginBottomLg":"15px","marginBottomXl":"20px","marginBottomXxl":"25px","__typename":"UnstyledListItemThemeSettings"},"yiq":{"light":"#ffffff","dark":"#000000","__typename":"YiqThemeSettings"},"colorLightness":{"primaryDark":0.36,"primaryLight":0.74,"primaryLighter":0.89,"primaryLightest":0.95,"infoDark":0.39,"infoLight":0.72,"infoLighter":0.85,"infoLightest":0.93,"successDark":0.24,"successLight":0.62,"successLighter":0.8,"successLightest":0.91,"warningDark":0.39,"warningLight":0.68,"warningLighter":0.84,"warningLightest":0.93,"dangerDark":0.41,"dangerLight":0.72,"dangerLighter":0.89,"dangerLightest":0.95,"__typename":"ColorLightnessThemeSettings"},"localOverride":false,"__typename":"Theme"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Loading/LoadingDot-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Loading/LoadingDot-1745505307000","value":{"title":"Loading..."},"localOverride":false},"CachedAsset:text:en_US-components/common/EmailVerification-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/common/EmailVerification-1745505307000","value":{"email.verification.title":"Email Verification Required","email.verification.message.update.email":"To participate in the community, you must first verify your email address. The verification email was sent to {email}. To change your email, visit My Settings.","email.verification.message.resend.email":"To participate in the community, you must first verify your email address. The verification email was sent to {email}. Resend email."},"localOverride":false},"CachedAsset:text:en_US-pages/tags/TagPage-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-pages/tags/TagPage-1745505307000","value":{"tagPageTitle":"Tag:\"{tagName}\" | {communityTitle}","tagPageForNodeTitle":"Tag:\"{tagName}\" in \"{title}\" | {communityTitle}","name":"Tags Page","tag":"Tag: {tagName}"},"localOverride":false},"Category:category:cis":{"__typename":"Category","id":"category:cis","entityType":"CATEGORY","displayId":"cis","nodeType":"category","depth":4,"title":"Core Infrastructure and Security","shortTitle":"Core Infrastructure and Security","parent":{"__ref":"Category:category:microsoft-security"}},"Category:category:top":{"__typename":"Category","id":"category:top","displayId":"top","nodeType":"category","depth":0,"title":"Top"},"Category:category:communities":{"__typename":"Category","id":"category:communities","displayId":"communities","nodeType":"category","depth":1,"parent":{"__ref":"Category:category:top"},"title":"Communities"},"Category:category:products-services":{"__typename":"Category","id":"category:products-services","displayId":"products-services","nodeType":"category","depth":2,"parent":{"__ref":"Category:category:communities"},"title":"Products"},"Category:category:microsoft-security":{"__typename":"Category","id":"category:microsoft-security","displayId":"microsoft-security","nodeType":"category","depth":3,"parent":{"__ref":"Category:category:products-services"},"title":"Microsoft Security","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Blog:board:CoreInfrastructureandSecurityBlog":{"__typename":"Blog","id":"board:CoreInfrastructureandSecurityBlog","entityType":"BLOG","displayId":"CoreInfrastructureandSecurityBlog","nodeType":"board","depth":5,"conversationStyle":"BLOG","title":"Core Infrastructure and Security Blog","description":"","avatar":null,"profileSettings":{"__typename":"ProfileSettings","language":null},"parent":{"__ref":"Category:category:cis"},"ancestors":{"__typename":"CoreNodeConnection","edges":[{"__typename":"CoreNodeEdge","node":{"__ref":"Community:community:gxcuf89792"}},{"__typename":"CoreNodeEdge","node":{"__ref":"Category:category:communities"}},{"__typename":"CoreNodeEdge","node":{"__ref":"Category:category:products-services"}},{"__typename":"CoreNodeEdge","node":{"__ref":"Category:category:microsoft-security"}},{"__typename":"CoreNodeEdge","node":{"__ref":"Category:category:cis"}}]},"userContext":{"__typename":"NodeUserContext","canAddAttachments":false,"canUpdateNode":false,"canPostMessages":false,"isSubscribed":false},"boardPolicies":{"__typename":"BoardPolicies","canPublishArticleOnCreate":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.forums.policy_can_publish_on_create_workflow_action.accessDenied","key":"error.lithium.policies.forums.policy_can_publish_on_create_workflow_action.accessDenied","args":[]}}},"theme":{"__ref":"Theme:customTheme1"},"shortTitle":"Core Infrastructure and Security Blog","tagPolicies":{"__typename":"TagPolicies","canSubscribeTagOnNode":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.labels.action.corenode.subscribe_labels.allow.accessDenied","key":"error.lithium.policies.labels.action.corenode.subscribe_labels.allow.accessDenied","args":[]}},"canManageTagDashboard":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.labels.action.corenode.admin_labels.allow.accessDenied","key":"error.lithium.policies.labels.action.corenode.admin_labels.allow.accessDenied","args":[]}}}},"CachedAsset:quilt:o365.prod:pages/tags/TagPage:board:CoreInfrastructureandSecurityBlog-1746740537100":{"__typename":"CachedAsset","id":"quilt:o365.prod:pages/tags/TagPage:board:CoreInfrastructureandSecurityBlog-1746740537100","value":{"id":"TagPage","container":{"id":"Common","headerProps":{"removeComponents":["community.widget.bannerWidget"],"__typename":"QuiltContainerSectionProps"},"items":[{"id":"tag-header-widget","layout":"ONE_COLUMN","bgColor":"var(--lia-bs-white)","showBorder":"BOTTOM","sectionEditLevel":"LOCKED","columnMap":{"main":[{"id":"tags.widget.TagsHeaderWidget","__typename":"QuiltComponent"}],"__typename":"OneSectionColumns"},"__typename":"OneColumnQuiltSection"},{"id":"messages-list-for-tag-widget","layout":"ONE_COLUMN","columnMap":{"main":[{"id":"messages.widget.messageListForNodeByRecentActivityWidget","props":{"viewVariant":{"type":"inline","props":{"useUnreadCount":true,"useViewCount":true,"useAuthorLogin":true,"clampBodyLines":3,"useAvatar":true,"useBoardIcon":false,"useKudosCount":true,"usePreviewMedia":true,"useTags":false,"useNode":true,"useNodeLink":true,"useTextBody":true,"truncateBodyLength":-1,"useBody":true,"useRepliesCount":true,"useSolvedBadge":true,"timeStampType":"conversation.lastPostingActivityTime","useMessageTimeLink":true,"clampSubjectLines":2}},"panelType":"divider","useTitle":false,"hideIfEmpty":false,"pagerVariant":{"type":"loadMore"},"style":"list","showTabs":true,"tabItemMap":{"default":{"mostRecent":true,"mostRecentUserContent":false,"newest":false},"additional":{"mostKudoed":true,"mostViewed":true,"mostReplies":false,"noReplies":false,"noSolutions":false,"solutions":false}}},"__typename":"QuiltComponent"}],"__typename":"OneSectionColumns"},"__typename":"OneColumnQuiltSection"}],"__typename":"QuiltContainer"},"__typename":"Quilt"},"localOverride":false},"CachedAsset:quiltWrapper:o365.prod:Common:1746797691813":{"__typename":"CachedAsset","id":"quiltWrapper:o365.prod:Common:1746797691813","value":{"id":"Common","header":{"backgroundImageProps":{"assetName":null,"backgroundSize":"COVER","backgroundRepeat":"NO_REPEAT","backgroundPosition":"CENTER_CENTER","lastModified":null,"__typename":"BackgroundImageProps"},"backgroundColor":"transparent","items":[{"id":"community.widget.navbarWidget","props":{"showUserName":true,"showRegisterLink":true,"useIconLanguagePicker":true,"useLabelLanguagePicker":true,"className":"QuiltComponent_lia-component-edit-mode__0nCcm","links":{"sideLinks":[],"mainLinks":[{"children":[],"linkType":"INTERNAL","id":"gxcuf89792","params":{},"routeName":"CommunityPage"},{"children":[],"linkType":"EXTERNAL","id":"external-link","url":"/Directory","target":"SELF"},{"children":[{"linkType":"INTERNAL","id":"microsoft365","params":{"categoryId":"microsoft365"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"windows","params":{"categoryId":"Windows"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"Common-microsoft365-copilot-link","params":{"categoryId":"Microsoft365Copilot"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-teams","params":{"categoryId":"MicrosoftTeams"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-securityand-compliance","params":{"categoryId":"microsoft-security"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"azure","params":{"categoryId":"Azure"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"Common-content_management-link","params":{"categoryId":"Content_Management"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"exchange","params":{"categoryId":"Exchange"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"windows-server","params":{"categoryId":"Windows-Server"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"outlook","params":{"categoryId":"Outlook"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-endpoint-manager","params":{"categoryId":"microsoftintune"},"routeName":"CategoryPage"},{"linkType":"EXTERNAL","id":"external-link-2","url":"/Directory","target":"SELF"}],"linkType":"EXTERNAL","id":"communities","url":"/","target":"BLANK"},{"children":[{"linkType":"INTERNAL","id":"a-i","params":{"categoryId":"AI"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"education-sector","params":{"categoryId":"EducationSector"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"partner-community","params":{"categoryId":"PartnerCommunity"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"i-t-ops-talk","params":{"categoryId":"ITOpsTalk"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"healthcare-and-life-sciences","params":{"categoryId":"HealthcareAndLifeSciences"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-mechanics","params":{"categoryId":"MicrosoftMechanics"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"public-sector","params":{"categoryId":"PublicSector"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"s-m-b","params":{"categoryId":"MicrosoftforNonprofits"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"io-t","params":{"categoryId":"IoT"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"startupsat-microsoft","params":{"categoryId":"StartupsatMicrosoft"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"driving-adoption","params":{"categoryId":"DrivingAdoption"},"routeName":"CategoryPage"},{"linkType":"EXTERNAL","id":"external-link-1","url":"/Directory","target":"SELF"}],"linkType":"EXTERNAL","id":"communities-1","url":"/","target":"SELF"},{"children":[],"linkType":"EXTERNAL","id":"external","url":"/Blogs","target":"SELF"},{"children":[],"linkType":"EXTERNAL","id":"external-1","url":"/Events","target":"SELF"},{"children":[{"linkType":"INTERNAL","id":"microsoft-learn-1","params":{"categoryId":"MicrosoftLearn"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-learn-blog","params":{"boardId":"MicrosoftLearnBlog","categoryId":"MicrosoftLearn"},"routeName":"BlogBoardPage"},{"linkType":"EXTERNAL","id":"external-10","url":"https://learningroomdirectory.microsoft.com/","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-3","url":"https://docs.microsoft.com/learn/dynamics365/?WT.mc_id=techcom_header-webpage-m365","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-4","url":"https://docs.microsoft.com/learn/m365/?wt.mc_id=techcom_header-webpage-m365","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-5","url":"https://docs.microsoft.com/learn/topics/sci/?wt.mc_id=techcom_header-webpage-m365","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-6","url":"https://docs.microsoft.com/learn/powerplatform/?wt.mc_id=techcom_header-webpage-powerplatform","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-7","url":"https://docs.microsoft.com/learn/github/?wt.mc_id=techcom_header-webpage-github","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-8","url":"https://docs.microsoft.com/learn/teams/?wt.mc_id=techcom_header-webpage-teams","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-9","url":"https://docs.microsoft.com/learn/dotnet/?wt.mc_id=techcom_header-webpage-dotnet","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-2","url":"https://docs.microsoft.com/learn/azure/?WT.mc_id=techcom_header-webpage-m365","target":"BLANK"}],"linkType":"INTERNAL","id":"microsoft-learn","params":{"categoryId":"MicrosoftLearn"},"routeName":"CategoryPage"},{"children":[],"linkType":"INTERNAL","id":"community-info-center","params":{"categoryId":"Community-Info-Center"},"routeName":"CategoryPage"}]},"style":{"boxShadow":"var(--lia-bs-box-shadow-sm)","controllerHighlightColor":"hsla(30, 100%, 50%)","linkFontWeight":"400","dropdownDividerMarginBottom":"10px","hamburgerBorderHover":"none","linkBoxShadowHover":"none","linkFontSize":"14px","backgroundOpacity":0.8,"controllerBorderRadius":"var(--lia-border-radius-50)","hamburgerBgColor":"transparent","hamburgerColor":"var(--lia-nav-controller-icon-color)","linkTextBorderBottom":"none","brandLogoHeight":"30px","linkBgHoverColor":"transparent","linkLetterSpacing":"normal","collapseMenuDividerOpacity":0.16,"dropdownPaddingBottom":"15px","paddingBottom":"15px","dropdownMenuOffset":"2px","hamburgerBgHoverColor":"transparent","borderBottom":"1px solid var(--lia-bs-border-color)","hamburgerBorder":"none","dropdownPaddingX":"10px","brandMarginRightSm":"10px","linkBoxShadow":"none","collapseMenuDividerBg":"var(--lia-nav-link-color)","linkColor":"var(--lia-bs-body-color)","linkJustifyContent":"flex-start","dropdownPaddingTop":"10px","controllerHighlightTextColor":"var(--lia-yiq-dark)","controllerTextColor":"var(--lia-nav-controller-icon-color)","background":{"imageAssetName":"","color":"var(--lia-bs-white)","size":"COVER","repeat":"NO_REPEAT","position":"CENTER_CENTER","imageLastModified":""},"linkBorderRadius":"var(--lia-bs-border-radius-sm)","linkHoverColor":"var(--lia-bs-body-color)","position":"FIXED","linkBorder":"none","linkTextBorderBottomHover":"2px solid var(--lia-bs-body-color)","brandMarginRight":"30px","hamburgerHoverColor":"var(--lia-nav-controller-icon-color)","linkBorderHover":"none","collapseMenuMarginLeft":"20px","linkFontStyle":"NORMAL","controllerTextHoverColor":"var(--lia-nav-controller-icon-hover-color)","linkPaddingX":"10px","linkPaddingY":"5px","paddingTop":"15px","linkTextTransform":"NONE","dropdownBorderColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","controllerBgHoverColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.1)","linkBgColor":"transparent","linkDropdownPaddingX":"var(--lia-nav-link-px)","linkDropdownPaddingY":"9px","controllerIconColor":"var(--lia-bs-body-color)","dropdownDividerMarginTop":"10px","linkGap":"10px","controllerIconHoverColor":"var(--lia-bs-body-color)"},"showSearchIcon":false,"languagePickerStyle":"iconAndLabel"},"__typename":"QuiltComponent"},{"id":"community.widget.breadcrumbWidget","props":{"backgroundColor":"transparent","linkHighlightColor":"var(--lia-bs-primary)","visualEffects":{"showBottomBorder":true},"linkTextColor":"var(--lia-bs-gray-700)"},"__typename":"QuiltComponent"},{"id":"custom.widget.community_banner","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"usePageWidth":false,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"},{"id":"custom.widget.HeroBanner","props":{"widgetVisibility":"signedInOrAnonymous","usePageWidth":false,"useTitle":true,"cMax_items":3,"useBackground":false,"title":"","lazyLoad":false,"widgetChooser":"custom.widget.HeroBanner"},"__typename":"QuiltComponent"}],"__typename":"QuiltWrapperSection"},"footer":{"backgroundImageProps":{"assetName":null,"backgroundSize":"COVER","backgroundRepeat":"NO_REPEAT","backgroundPosition":"CENTER_CENTER","lastModified":null,"__typename":"BackgroundImageProps"},"backgroundColor":"transparent","items":[{"id":"custom.widget.MicrosoftFooter","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"}],"__typename":"QuiltWrapperSection"},"__typename":"QuiltWrapper","localOverride":false},"localOverride":false},"CachedAsset:text:en_US-components/common/ActionFeedback-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/common/ActionFeedback-1745505307000","value":{"joinedGroupHub.title":"Welcome","joinedGroupHub.message":"You are now a member of this group and are subscribed to updates.","groupHubInviteNotFound.title":"Invitation Not Found","groupHubInviteNotFound.message":"Sorry, we could not find your invitation to the group. The owner may have canceled the invite.","groupHubNotFound.title":"Group Not Found","groupHubNotFound.message":"The grouphub you tried to join does not exist. It may have been deleted.","existingGroupHubMember.title":"Already Joined","existingGroupHubMember.message":"You are already a member of this group.","accountLocked.title":"Account Locked","accountLocked.message":"Your account has been locked due to multiple failed attempts. Try again in {lockoutTime} minutes.","editedGroupHub.title":"Changes Saved","editedGroupHub.message":"Your group has been updated.","leftGroupHub.title":"Goodbye","leftGroupHub.message":"You are no longer a member of this group and will not receive future updates.","deletedGroupHub.title":"Deleted","deletedGroupHub.message":"The group has been deleted.","groupHubCreated.title":"Group Created","groupHubCreated.message":"{groupHubName} is ready to use","accountClosed.title":"Account Closed","accountClosed.message":"The account has been closed and you will now be redirected to the homepage","resetTokenExpired.title":"Reset Password Link has Expired","resetTokenExpired.message":"Try resetting your password again","invalidUrl.title":"Invalid URL","invalidUrl.message":"The URL you're using is not recognized. Verify your URL and try again.","accountClosedForUser.title":"Account Closed","accountClosedForUser.message":"{userName}'s account is closed","inviteTokenInvalid.title":"Invitation Invalid","inviteTokenInvalid.message":"Your invitation to the community has been canceled or expired.","inviteTokenError.title":"Invitation Verification Failed","inviteTokenError.message":"The url you are utilizing is not recognized. Verify your URL and try again","pageNotFound.title":"Access Denied","pageNotFound.message":"You do not have access to this area of the community or it doesn't exist","eventAttending.title":"Responded as Attending","eventAttending.message":"You'll be notified when there's new activity and reminded as the event approaches","eventInterested.title":"Responded as Interested","eventInterested.message":"You'll be notified when there's new activity and reminded as the event approaches","eventNotFound.title":"Event Not Found","eventNotFound.message":"The event you tried to respond to does not exist.","redirectToRelatedPage.title":"Showing Related Content","redirectToRelatedPageForBaseUsers.title":"Showing Related Content","redirectToRelatedPageForBaseUsers.message":"The content you are trying to access is archived","redirectToRelatedPage.message":"The content you are trying to access is archived","relatedUrl.archivalLink.flyoutMessage":"The content you are trying to access is archived View Archived Content"},"localOverride":false},"CachedAsset:component:custom.widget.community_banner-en-us-1746740527707":{"__typename":"CachedAsset","id":"component:custom.widget.community_banner-en-us-1746740527707","value":{"component":{"id":"custom.widget.community_banner","template":{"id":"community_banner","markupLanguage":"HANDLEBARS","style":".community-banner {\n a.top-bar.btn {\n top: 0px;\n width: 100%;\n z-index: 999;\n text-align: center;\n left: 0px;\n background: #0068b8;\n color: white;\n padding: 10px 0px;\n display: block;\n box-shadow: none !important;\n border: none !important;\n border-radius: none !important;\n margin: 0px !important;\n font-size: 14px;\n }\n}\n","texts":{},"defaults":{"config":{"applicablePages":[],"description":"community announcement text","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.community_banner","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"community announcement text","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":{"css":".custom_widget_community_banner_community-banner_1x9u2_1 {\n a.custom_widget_community_banner_top-bar_1x9u2_2.custom_widget_community_banner_btn_1x9u2_2 {\n top: 0;\n width: 100%;\n z-index: 999;\n text-align: center;\n left: 0;\n background: #0068b8;\n color: white;\n padding: 0.625rem 0;\n display: block;\n box-shadow: none !important;\n border: none !important;\n border-radius: none !important;\n margin: 0 !important;\n font-size: 0.875rem;\n }\n}\n","tokens":{"community-banner":"custom_widget_community_banner_community-banner_1x9u2_1","top-bar":"custom_widget_community_banner_top-bar_1x9u2_2","btn":"custom_widget_community_banner_btn_1x9u2_2"}},"form":null},"localOverride":false},"CachedAsset:component:custom.widget.HeroBanner-en-us-1746740527707":{"__typename":"CachedAsset","id":"component:custom.widget.HeroBanner-en-us-1746740527707","value":{"component":{"id":"custom.widget.HeroBanner","template":{"id":"HeroBanner","markupLanguage":"REACT","style":null,"texts":{"searchPlaceholderText":"Search this community","followActionText":"Follow","unfollowActionText":"Following","searchOnHoverText":"Please enter your search term(s) and then press return key to complete a search.","blogs.sidebar.pagetitle":"Latest Blogs | Microsoft Tech Community","followThisNode":"Follow this node","unfollowThisNode":"Unfollow this node"},"defaults":{"config":{"applicablePages":[],"description":null,"fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[{"id":"max_items","dataType":"NUMBER","list":false,"defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"control":"INPUT","__typename":"PropDefinition"}],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.HeroBanner","form":{"fields":[{"id":"widgetChooser","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"title","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useTitle","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useBackground","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"widgetVisibility","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"moreOptions","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"cMax_items","validation":null,"noValidation":null,"dataType":"NUMBER","list":false,"control":"INPUT","defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"__typename":"FormField"}],"layout":{"rows":[{"id":"widgetChooserGroup","type":"fieldset","as":null,"items":[{"id":"widgetChooser","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"titleGroup","type":"fieldset","as":null,"items":[{"id":"title","className":null,"__typename":"FormFieldRef"},{"id":"useTitle","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"useBackground","type":"fieldset","as":null,"items":[{"id":"useBackground","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"widgetVisibility","type":"fieldset","as":null,"items":[{"id":"widgetVisibility","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"moreOptionsGroup","type":"fieldset","as":null,"items":[{"id":"moreOptions","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"componentPropsGroup","type":"fieldset","as":null,"items":[{"id":"cMax_items","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"}],"actionButtons":null,"className":"custom_widget_HeroBanner_form","formGroupFieldSeparator":"divider","__typename":"FormLayout"},"__typename":"Form"},"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":null,"fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[{"id":"max_items","dataType":"NUMBER","list":false,"defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"control":"INPUT","__typename":"PropDefinition"}],"__typename":"ComponentProperties"},"form":{"fields":[{"id":"widgetChooser","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"title","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useTitle","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useBackground","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"widgetVisibility","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"moreOptions","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"cMax_items","validation":null,"noValidation":null,"dataType":"NUMBER","list":false,"control":"INPUT","defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"__typename":"FormField"}],"layout":{"rows":[{"id":"widgetChooserGroup","type":"fieldset","as":null,"items":[{"id":"widgetChooser","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"titleGroup","type":"fieldset","as":null,"items":[{"id":"title","className":null,"__typename":"FormFieldRef"},{"id":"useTitle","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"useBackground","type":"fieldset","as":null,"items":[{"id":"useBackground","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"widgetVisibility","type":"fieldset","as":null,"items":[{"id":"widgetVisibility","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"moreOptionsGroup","type":"fieldset","as":null,"items":[{"id":"moreOptions","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"componentPropsGroup","type":"fieldset","as":null,"items":[{"id":"cMax_items","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"}],"actionButtons":null,"className":"custom_widget_HeroBanner_form","formGroupFieldSeparator":"divider","__typename":"FormLayout"},"__typename":"Form"},"__typename":"Component","localOverride":false},"globalCss":null,"form":{"fields":[{"id":"widgetChooser","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"title","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useTitle","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useBackground","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"widgetVisibility","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"moreOptions","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"cMax_items","validation":null,"noValidation":null,"dataType":"NUMBER","list":false,"control":"INPUT","defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"__typename":"FormField"}],"layout":{"rows":[{"id":"widgetChooserGroup","type":"fieldset","as":null,"items":[{"id":"widgetChooser","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"titleGroup","type":"fieldset","as":null,"items":[{"id":"title","className":null,"__typename":"FormFieldRef"},{"id":"useTitle","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"useBackground","type":"fieldset","as":null,"items":[{"id":"useBackground","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"widgetVisibility","type":"fieldset","as":null,"items":[{"id":"widgetVisibility","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"moreOptionsGroup","type":"fieldset","as":null,"items":[{"id":"moreOptions","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"componentPropsGroup","type":"fieldset","as":null,"items":[{"id":"cMax_items","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"}],"actionButtons":null,"className":"custom_widget_HeroBanner_form","formGroupFieldSeparator":"divider","__typename":"FormLayout"},"__typename":"Form"}},"localOverride":false},"CachedAsset:component:custom.widget.MicrosoftFooter-en-us-1746740527707":{"__typename":"CachedAsset","id":"component:custom.widget.MicrosoftFooter-en-us-1746740527707","value":{"component":{"id":"custom.widget.MicrosoftFooter","template":{"id":"MicrosoftFooter","markupLanguage":"HANDLEBARS","style":".context-uhf {\n min-width: 280px;\n font-size: 15px;\n box-sizing: border-box;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n & *,\n & *:before,\n & *:after {\n box-sizing: inherit;\n }\n a.c-uhff-link {\n color: #616161;\n word-break: break-word;\n text-decoration: none;\n }\n &a:link,\n &a:focus,\n &a:hover,\n &a:active,\n &a:visited {\n text-decoration: none;\n color: inherit;\n }\n & div {\n font-family: 'Segoe UI', SegoeUI, 'Helvetica Neue', Helvetica, Arial, sans-serif;\n }\n}\n.c-uhff {\n background: #f2f2f2;\n margin: -1.5625;\n width: auto;\n height: auto;\n}\n.c-uhff-nav {\n margin: 0 auto;\n max-width: calc(1600px + 10%);\n padding: 0 5%;\n box-sizing: inherit;\n &:before,\n &:after {\n content: ' ';\n display: table;\n clear: left;\n }\n @media only screen and (max-width: 1083px) {\n padding-left: 12px;\n }\n .c-heading-4 {\n color: #616161;\n word-break: break-word;\n font-size: 15px;\n line-height: 20px;\n padding: 36px 0 4px;\n font-weight: 600;\n }\n .c-uhff-nav-row {\n .c-uhff-nav-group {\n display: block;\n float: left;\n min-height: 1px;\n vertical-align: text-top;\n padding: 0 12px;\n width: 100%;\n zoom: 1;\n &:first-child {\n padding-left: 0;\n @media only screen and (max-width: 1083px) {\n padding-left: 12px;\n }\n }\n @media only screen and (min-width: 540px) and (max-width: 1082px) {\n width: 33.33333%;\n }\n @media only screen and (min-width: 1083px) {\n width: 16.6666666667%;\n }\n ul.c-list.f-bare {\n font-size: 11px;\n line-height: 16px;\n margin-top: 0;\n margin-bottom: 0;\n padding-left: 0;\n list-style-type: none;\n li {\n word-break: break-word;\n padding: 8px 0;\n margin: 0;\n }\n }\n }\n }\n}\n.c-uhff-base {\n background: #f2f2f2;\n margin: 0 auto;\n max-width: calc(1600px + 10%);\n padding: 30px 5% 16px;\n &:before,\n &:after {\n content: ' ';\n display: table;\n }\n &:after {\n clear: both;\n }\n a.c-uhff-ccpa {\n font-size: 11px;\n line-height: 16px;\n float: left;\n margin: 3px 0;\n }\n a.c-uhff-ccpa:hover {\n text-decoration: underline;\n }\n ul.c-list {\n font-size: 11px;\n line-height: 16px;\n float: right;\n margin: 3px 0;\n color: #616161;\n li {\n padding: 0 24px 4px 0;\n display: inline-block;\n }\n }\n .c-list.f-bare {\n padding-left: 0;\n list-style-type: none;\n }\n @media only screen and (max-width: 1083px) {\n display: flex;\n flex-wrap: wrap;\n padding: 30px 24px 16px;\n }\n}\n\n.social-share {\n position: fixed;\n top: 60%;\n transform: translateY(-50%);\n left: 0;\n z-index: 1000;\n}\n\n.sharing-options {\n list-style: none;\n padding: 0;\n margin: 0;\n display: block;\n flex-direction: column;\n background-color: white;\n width: 43px;\n border-radius: 0px 7px 7px 0px;\n}\n.linkedin-icon {\n border-top-right-radius: 7px;\n}\n.linkedin-icon:hover {\n border-radius: 0;\n}\n.social-share-rss-image {\n border-bottom-right-radius: 7px;\n}\n.social-share-rss-image:hover {\n border-radius: 0;\n}\n\n.social-link-footer {\n position: relative;\n display: block;\n margin: -2px 0;\n transition: all 0.2s ease;\n}\n.social-link-footer:hover .linkedin-icon {\n border-radius: 0;\n}\n.social-link-footer:hover .social-share-rss-image {\n border-radius: 0;\n}\n\n.social-link-footer img {\n width: 40px;\n height: auto;\n transition: filter 0.3s ease;\n}\n\n.social-share-list {\n width: 40px;\n}\n.social-share-rss-image {\n width: 40px;\n}\n\n.share-icon {\n border: 2px solid transparent;\n display: inline-block;\n position: relative;\n}\n\n.share-icon:hover {\n opacity: 1;\n border: 2px solid white;\n box-sizing: border-box;\n}\n\n.share-icon:hover .label {\n opacity: 1;\n visibility: visible;\n border: 2px solid white;\n box-sizing: border-box;\n border-left: none;\n}\n\n.label {\n position: absolute;\n left: 100%;\n white-space: nowrap;\n opacity: 0;\n visibility: hidden;\n transition: all 0.2s ease;\n color: white;\n border-radius: 0 10 0 10px;\n top: 50%;\n transform: translateY(-50%);\n height: 40px;\n border-radius: 0 6px 6px 0;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 20px 5px 20px 8px;\n margin-left: -1px;\n}\n.linkedin {\n background-color: #0474b4;\n}\n.facebook {\n background-color: #3c5c9c;\n}\n.twitter {\n background-color: white;\n color: black;\n}\n.reddit {\n background-color: #fc4404;\n}\n.mail {\n background-color: #848484;\n}\n.bluesky {\n background-color: white;\n color: black;\n}\n.rss {\n background-color: #ec7b1c;\n}\n#RSS {\n width: 40px;\n height: 40px;\n}\n\n@media (max-width: 991px) {\n .social-share {\n display: none;\n }\n}\n","texts":{"New tab":"What's New","New 1":"Surface Laptop Studio 2","New 2":"Surface Laptop Go 3","New 3":"Surface Pro 9","New 4":"Surface Laptop 5","New 5":"Surface Studio 2+","New 6":"Copilot in Windows","New 7":"Microsoft 365","New 8":"Windows 11 apps","Store tab":"Microsoft Store","Store 1":"Account Profile","Store 2":"Download Center","Store 3":"Microsoft Store Support","Store 4":"Returns","Store 5":"Order tracking","Store 6":"Certified Refurbished","Store 7":"Microsoft Store Promise","Store 8":"Flexible Payments","Education tab":"Education","Edu 1":"Microsoft in education","Edu 2":"Devices for education","Edu 3":"Microsoft Teams for Education","Edu 4":"Microsoft 365 Education","Edu 5":"How to buy for your school","Edu 6":"Educator Training and development","Edu 7":"Deals for students and parents","Edu 8":"Azure for students","Business tab":"Business","Bus 1":"Microsoft Cloud","Bus 2":"Microsoft Security","Bus 3":"Dynamics 365","Bus 4":"Microsoft 365","Bus 5":"Microsoft Power Platform","Bus 6":"Microsoft Teams","Bus 7":"Microsoft Industry","Bus 8":"Small Business","Developer tab":"Developer & IT","Dev 1":"Azure","Dev 2":"Developer Center","Dev 3":"Documentation","Dev 4":"Microsoft Learn","Dev 5":"Microsoft Tech Community","Dev 6":"Azure Marketplace","Dev 7":"AppSource","Dev 8":"Visual Studio","Company tab":"Company","Com 1":"Careers","Com 2":"About Microsoft","Com 3":"Company News","Com 4":"Privacy at Microsoft","Com 5":"Investors","Com 6":"Diversity and inclusion","Com 7":"Accessiblity","Com 8":"Sustainibility"},"defaults":{"config":{"applicablePages":[],"description":"The Microsoft Footer","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.MicrosoftFooter","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"The Microsoft Footer","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":{"css":".custom_widget_MicrosoftFooter_context-uhf_105bp_1 {\n min-width: 17.5rem;\n font-size: 0.9375rem;\n box-sizing: border-box;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n & *,\n & *:before,\n & *:after {\n box-sizing: inherit;\n }\n a.custom_widget_MicrosoftFooter_c-uhff-link_105bp_12 {\n color: #616161;\n word-break: break-word;\n text-decoration: none;\n }\n &a:link,\n &a:focus,\n &a:hover,\n &a:active,\n &a:visited {\n text-decoration: none;\n color: inherit;\n }\n & div {\n font-family: 'Segoe UI', SegoeUI, 'Helvetica Neue', Helvetica, Arial, sans-serif;\n }\n}\n.custom_widget_MicrosoftFooter_c-uhff_105bp_12 {\n background: #f2f2f2;\n margin: -1.5625;\n width: auto;\n height: auto;\n}\n.custom_widget_MicrosoftFooter_c-uhff-nav_105bp_35 {\n margin: 0 auto;\n max-width: calc(100rem + 10%);\n padding: 0 5%;\n box-sizing: inherit;\n &:before,\n &:after {\n content: ' ';\n display: table;\n clear: left;\n }\n @media only screen and (max-width: 1083px) {\n padding-left: 0.75rem;\n }\n .custom_widget_MicrosoftFooter_c-heading-4_105bp_49 {\n color: #616161;\n word-break: break-word;\n font-size: 0.9375rem;\n line-height: 1.25rem;\n padding: 2.25rem 0 0.25rem;\n font-weight: 600;\n }\n .custom_widget_MicrosoftFooter_c-uhff-nav-row_105bp_57 {\n .custom_widget_MicrosoftFooter_c-uhff-nav-group_105bp_58 {\n display: block;\n float: left;\n min-height: 0.0625rem;\n vertical-align: text-top;\n padding: 0 0.75rem;\n width: 100%;\n zoom: 1;\n &:first-child {\n padding-left: 0;\n @media only screen and (max-width: 1083px) {\n padding-left: 0.75rem;\n }\n }\n @media only screen and (min-width: 540px) and (max-width: 1082px) {\n width: 33.33333%;\n }\n @media only screen and (min-width: 1083px) {\n width: 16.6666666667%;\n }\n ul.custom_widget_MicrosoftFooter_c-list_105bp_78.custom_widget_MicrosoftFooter_f-bare_105bp_78 {\n font-size: 0.6875rem;\n line-height: 1rem;\n margin-top: 0;\n margin-bottom: 0;\n padding-left: 0;\n list-style-type: none;\n li {\n word-break: break-word;\n padding: 0.5rem 0;\n margin: 0;\n }\n }\n }\n }\n}\n.custom_widget_MicrosoftFooter_c-uhff-base_105bp_94 {\n background: #f2f2f2;\n margin: 0 auto;\n max-width: calc(100rem + 10%);\n padding: 1.875rem 5% 1rem;\n &:before,\n &:after {\n content: ' ';\n display: table;\n }\n &:after {\n clear: both;\n }\n a.custom_widget_MicrosoftFooter_c-uhff-ccpa_105bp_107 {\n font-size: 0.6875rem;\n line-height: 1rem;\n float: left;\n margin: 0.1875rem 0;\n }\n a.custom_widget_MicrosoftFooter_c-uhff-ccpa_105bp_107:hover {\n text-decoration: underline;\n }\n ul.custom_widget_MicrosoftFooter_c-list_105bp_78 {\n font-size: 0.6875rem;\n line-height: 1rem;\n float: right;\n margin: 0.1875rem 0;\n color: #616161;\n li {\n padding: 0 1.5rem 0.25rem 0;\n display: inline-block;\n }\n }\n .custom_widget_MicrosoftFooter_c-list_105bp_78.custom_widget_MicrosoftFooter_f-bare_105bp_78 {\n padding-left: 0;\n list-style-type: none;\n }\n @media only screen and (max-width: 1083px) {\n display: flex;\n flex-wrap: wrap;\n padding: 1.875rem 1.5rem 1rem;\n }\n}\n.custom_widget_MicrosoftFooter_social-share_105bp_138 {\n position: fixed;\n top: 60%;\n transform: translateY(-50%);\n left: 0;\n z-index: 1000;\n}\n.custom_widget_MicrosoftFooter_sharing-options_105bp_146 {\n list-style: none;\n padding: 0;\n margin: 0;\n display: block;\n flex-direction: column;\n background-color: white;\n width: 2.6875rem;\n border-radius: 0 0.4375rem 0.4375rem 0;\n}\n.custom_widget_MicrosoftFooter_linkedin-icon_105bp_156 {\n border-top-right-radius: 7px;\n}\n.custom_widget_MicrosoftFooter_linkedin-icon_105bp_156:hover {\n border-radius: 0;\n}\n.custom_widget_MicrosoftFooter_social-share-rss-image_105bp_162 {\n border-bottom-right-radius: 7px;\n}\n.custom_widget_MicrosoftFooter_social-share-rss-image_105bp_162:hover {\n border-radius: 0;\n}\n.custom_widget_MicrosoftFooter_social-link-footer_105bp_169 {\n position: relative;\n display: block;\n margin: -0.125rem 0;\n transition: all 0.2s ease;\n}\n.custom_widget_MicrosoftFooter_social-link-footer_105bp_169:hover .custom_widget_MicrosoftFooter_linkedin-icon_105bp_156 {\n border-radius: 0;\n}\n.custom_widget_MicrosoftFooter_social-link-footer_105bp_169:hover .custom_widget_MicrosoftFooter_social-share-rss-image_105bp_162 {\n border-radius: 0;\n}\n.custom_widget_MicrosoftFooter_social-link-footer_105bp_169 img {\n width: 2.5rem;\n height: auto;\n transition: filter 0.3s ease;\n}\n.custom_widget_MicrosoftFooter_social-share-list_105bp_188 {\n width: 2.5rem;\n}\n.custom_widget_MicrosoftFooter_social-share-rss-image_105bp_162 {\n width: 2.5rem;\n}\n.custom_widget_MicrosoftFooter_share-icon_105bp_195 {\n border: 2px solid transparent;\n display: inline-block;\n position: relative;\n}\n.custom_widget_MicrosoftFooter_share-icon_105bp_195:hover {\n opacity: 1;\n border: 2px solid white;\n box-sizing: border-box;\n}\n.custom_widget_MicrosoftFooter_share-icon_105bp_195:hover .custom_widget_MicrosoftFooter_label_105bp_207 {\n opacity: 1;\n visibility: visible;\n border: 2px solid white;\n box-sizing: border-box;\n border-left: none;\n}\n.custom_widget_MicrosoftFooter_label_105bp_207 {\n position: absolute;\n left: 100%;\n white-space: nowrap;\n opacity: 0;\n visibility: hidden;\n transition: all 0.2s ease;\n color: white;\n border-radius: 0 10 0 0.625rem;\n top: 50%;\n transform: translateY(-50%);\n height: 2.5rem;\n border-radius: 0 0.375rem 0.375rem 0;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 1.25rem 0.3125rem 1.25rem 0.5rem;\n margin-left: -0.0625rem;\n}\n.custom_widget_MicrosoftFooter_linkedin_105bp_156 {\n background-color: #0474b4;\n}\n.custom_widget_MicrosoftFooter_facebook_105bp_237 {\n background-color: #3c5c9c;\n}\n.custom_widget_MicrosoftFooter_twitter_105bp_240 {\n background-color: white;\n color: black;\n}\n.custom_widget_MicrosoftFooter_reddit_105bp_244 {\n background-color: #fc4404;\n}\n.custom_widget_MicrosoftFooter_mail_105bp_247 {\n background-color: #848484;\n}\n.custom_widget_MicrosoftFooter_bluesky_105bp_250 {\n background-color: white;\n color: black;\n}\n.custom_widget_MicrosoftFooter_rss_105bp_254 {\n background-color: #ec7b1c;\n}\n#custom_widget_MicrosoftFooter_RSS_105bp_1 {\n width: 2.5rem;\n height: 2.5rem;\n}\n@media (max-width: 991px) {\n .custom_widget_MicrosoftFooter_social-share_105bp_138 {\n display: none;\n }\n}\n","tokens":{"context-uhf":"custom_widget_MicrosoftFooter_context-uhf_105bp_1","c-uhff-link":"custom_widget_MicrosoftFooter_c-uhff-link_105bp_12","c-uhff":"custom_widget_MicrosoftFooter_c-uhff_105bp_12","c-uhff-nav":"custom_widget_MicrosoftFooter_c-uhff-nav_105bp_35","c-heading-4":"custom_widget_MicrosoftFooter_c-heading-4_105bp_49","c-uhff-nav-row":"custom_widget_MicrosoftFooter_c-uhff-nav-row_105bp_57","c-uhff-nav-group":"custom_widget_MicrosoftFooter_c-uhff-nav-group_105bp_58","c-list":"custom_widget_MicrosoftFooter_c-list_105bp_78","f-bare":"custom_widget_MicrosoftFooter_f-bare_105bp_78","c-uhff-base":"custom_widget_MicrosoftFooter_c-uhff-base_105bp_94","c-uhff-ccpa":"custom_widget_MicrosoftFooter_c-uhff-ccpa_105bp_107","social-share":"custom_widget_MicrosoftFooter_social-share_105bp_138","sharing-options":"custom_widget_MicrosoftFooter_sharing-options_105bp_146","linkedin-icon":"custom_widget_MicrosoftFooter_linkedin-icon_105bp_156","social-share-rss-image":"custom_widget_MicrosoftFooter_social-share-rss-image_105bp_162","social-link-footer":"custom_widget_MicrosoftFooter_social-link-footer_105bp_169","social-share-list":"custom_widget_MicrosoftFooter_social-share-list_105bp_188","share-icon":"custom_widget_MicrosoftFooter_share-icon_105bp_195","label":"custom_widget_MicrosoftFooter_label_105bp_207","linkedin":"custom_widget_MicrosoftFooter_linkedin_105bp_156","facebook":"custom_widget_MicrosoftFooter_facebook_105bp_237","twitter":"custom_widget_MicrosoftFooter_twitter_105bp_240","reddit":"custom_widget_MicrosoftFooter_reddit_105bp_244","mail":"custom_widget_MicrosoftFooter_mail_105bp_247","bluesky":"custom_widget_MicrosoftFooter_bluesky_105bp_250","rss":"custom_widget_MicrosoftFooter_rss_105bp_254","RSS":"custom_widget_MicrosoftFooter_RSS_105bp_1"}},"form":null},"localOverride":false},"CachedAsset:text:en_US-components/community/Breadcrumb-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/community/Breadcrumb-1745505307000","value":{"navLabel":"Breadcrumbs","dropdown":"Additional parent page navigation"},"localOverride":false},"CachedAsset:text:en_US-components/tags/TagsHeaderWidget-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/tags/TagsHeaderWidget-1745505307000","value":{"tag":"{tagName}","topicsCount":"{count} {count, plural, one {Topic} other {Topics}}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageListForNodeByRecentActivityWidget-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageListForNodeByRecentActivityWidget-1745505307000","value":{"title@userScope:other":"Recent Content","title@userScope:self":"Contributions","title@board:FORUM@userScope:other":"Recent Discussions","title@board:BLOG@userScope:other":"Recent Blogs","emptyDescription":"No content to show","MessageListForNodeByRecentActivityWidgetEditor.nodeScope.label":"Scope","title@instance:1722894000155":"Recent Discussions","title@instance:1727367112619":"Recent Blog Articles","title@instance:1727367069748":"Recent Discussions","title@instance:1727366213114":"Latest Discussions","title@instance:1727899609720":"","title@instance:1727363308925":"Latest Discussions","title@instance:1737115580352":"Latest Articles","title@instance:1720453418992":"Recent Discssions","title@instance:1727365950181":"Latest Blog Articles","title@instance:bmDPnI":"Latest Blog Articles","title@instance:IiDDJZ":"Latest Blog Articles","title@instance:1721244347979":"Latest blog posts","title@instance:1728383752171":"Related Content","title@instance:1722893956545":"Latest Skilling Resources","title@instance:dhcgCU":"Latest Discussions"},"localOverride":false},"Category:category:Exchange":{"__typename":"Category","id":"category:Exchange","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Outlook":{"__typename":"Category","id":"category:Outlook","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Community-Info-Center":{"__typename":"Category","id":"category:Community-Info-Center","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:EducationSector":{"__typename":"Category","id":"category:EducationSector","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:DrivingAdoption":{"__typename":"Category","id":"category:DrivingAdoption","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Azure":{"__typename":"Category","id":"category:Azure","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Windows-Server":{"__typename":"Category","id":"category:Windows-Server","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftTeams":{"__typename":"Category","id":"category:MicrosoftTeams","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:PublicSector":{"__typename":"Category","id":"category:PublicSector","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:microsoft365":{"__typename":"Category","id":"category:microsoft365","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:IoT":{"__typename":"Category","id":"category:IoT","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:HealthcareAndLifeSciences":{"__typename":"Category","id":"category:HealthcareAndLifeSciences","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:ITOpsTalk":{"__typename":"Category","id":"category:ITOpsTalk","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftLearn":{"__typename":"Category","id":"category:MicrosoftLearn","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Blog:board:MicrosoftLearnBlog":{"__typename":"Blog","id":"board:MicrosoftLearnBlog","blogPolicies":{"__typename":"BlogPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:AI":{"__typename":"Category","id":"category:AI","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftMechanics":{"__typename":"Category","id":"category:MicrosoftMechanics","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftforNonprofits":{"__typename":"Category","id":"category:MicrosoftforNonprofits","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:StartupsatMicrosoft":{"__typename":"Category","id":"category:StartupsatMicrosoft","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:PartnerCommunity":{"__typename":"Category","id":"category:PartnerCommunity","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Microsoft365Copilot":{"__typename":"Category","id":"category:Microsoft365Copilot","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Windows":{"__typename":"Category","id":"category:Windows","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Content_Management":{"__typename":"Category","id":"category:Content_Management","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:microsoftintune":{"__typename":"Category","id":"category:microsoftintune","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Conversation:conversation:3047258":{"__typename":"Conversation","id":"conversation:3047258","topic":{"__typename":"BlogTopicMessage","uid":3047258},"lastPostingActivityTime":"2024-08-28T23:29:43.152-07:00","solved":false},"User:user:399999":{"__typename":"User","uid":399999,"login":"PaulHarrison","registrationData":{"__typename":"RegistrationData","status":null},"deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/dS0zOTk5OTktNTU0OTM0aTc2MzFFQjI3RUREN0FDNjM"},"id":"user:399999"},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMDQ3MjU4LTMzNjIxNWlGMzM5QjYwMjZFMUNDMzBF?revision=2\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMDQ3MjU4LTMzNjIxNWlGMzM5QjYwMjZFMUNDMzBF?revision=2","title":"PaulHarrison_0-1640716009126.png","associationType":"BODY","width":1600,"height":1257,"altText":null},"BlogTopicMessage:message:3047258":{"__typename":"BlogTopicMessage","subject":"Recurring Active Directory Checks","conversation":{"__ref":"Conversation:conversation:3047258"},"id":"message:3047258","revisionNum":2,"uid":3047258,"depth":0,"board":{"__ref":"Blog:board:CoreInfrastructureandSecurityBlog"},"author":{"__ref":"User:user:399999"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":" Check your Active Directory environment for common mistakes automatically. ","introduction":"","metrics":{"__typename":"MessageMetrics","views":34660},"postTime":"2021-12-28T10:38:47.032-08:00","lastPublishTime":"2021-12-28T10:38:47.032-08:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" Q: I just had an Active Directory (AD) or Active Directory Security health assessment from Microsoft, and they found some stuff I didn’t know about, or they found other items I knew to check for but forgot about. While I want to get another assessment done in another year or two, I want to stay on top of some of these items in the meantime. Do you have an easy way to monitor known problems? \n \n A: Yes! It is easy to forget about some one-off configurations that were only done temporarily, or someone can make a mistake and forget to catch it. While the Microsoft assessments catch a ton of items that are much more complex, we can make a simple script check common problems regularly. \n \n There are a lot of configuration options in Active Directory Domain Services (ADDS) and Microsoft assessments are the best way to find problems with configurations, but some items are customized for each customer. The other day a customer mentioned that they wanted to scan for accounts that had not logged in recently and disable the unused accounts, so they could investigate if they are needed anymore and decommission them. They wanted to track a few other items though, so I wrote the following script. This way items that are easy to fix, but hard to remember, are automatically checked for them. \n \n Disclaimer: The sample scripts are not supported under any Microsoft standard support program or service. The sample scripts are provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages. \n \n I will walk through queries that can be used to measure several different items, then how to make them a little fancier, then show the whole script that I put together the other day. It is easy to modify if you want slightly different information. If you just want a copy of the code, you can get a copy here. \n \n Occasionally administrators join a computer to the domain and forget to move the computer object to the proper Organizational Unit (OU). If computers are not in the proper OU, then they will not get the proper Group Policy Objects (GPOs) applied, which can cause unexpected behavior. \n \n The following query checks for any forgotten computers in the Computers container: \n \n Get-ADObject -SearchBase \"CN=Computers,DC=Contoso,DC=com\" -Filter * \n \n \n The Users container should not have the accounts for admins or users in it. To get all the objects in the Users container, we use a very similar query: \n \n Get-ADObject -SearchBase \"CN=Users,DC=Contoso,DC=com\" -Filter * \n \n \n Unfortunately, this gives a bunch of items that we don’t want to report on, since we don’t mind some default objects from when the domain was created being in our Users container. To mitigate this, I remove critical system objects which include items like krbtgt, the RID-500 account, and groups like Domain Admins, and Domain Users. I also ignore accounts used by AAD (Azure Active Directory) Connect. If you have Exchange installed in your environment and have SystemMailbox objects in Users then you could exclude those too. \n \n $NormalObjectsInUsers = @('DnsAdmins', 'DnsUpdateProxy') #This can be populated with additional exceptions you want to allow \n\n$ExtraObjectsInUsersContainer = Get-ADObject -SearchBase $('CN=Users,' + $DomainDN) -Filter { ObjectClass -ne 'container' } -Properties isCriticalSystemObject, samaccountname -Server $domain | \n\nWhere-Object { $_.SamAccountName -notin $NormalObjectsInUsers -and $_.isCriticalSystemObject -ne $true -and $_.SamAccountName -ne $Null -and -not($_.samaccountname.startswith('AAD_')) -and -not($_.samaccountname.startswith('MOL_')) -and ($_.samaccountname -ne 'SUPPORT_388945a0') -and -not($_.samaccountname -like 'CAS_*}*') } \n \n \n Test GPOs can be created and forgotten, so I like a report of all my unlinked GPOs so that I can clean them up. This checks for all unlinked GPOs. Even in small environments, this takes several seconds to run. \n \n Get-GPO -All | Where-Object {$_ | Get-GPOReport -ReportType XML | Select-String -NotMatch \"<LinksTo>\"} \n \n \n Most organizations require users to change their password periodically. Admins sometimes fall behind on changing passwords for service accounts and there are accounts that get forgotten about and are not used, so this checks for all enabled accounts that have not had the password changed within the last year. \n \n $old = (Get-Date).AddDays(-365) \n\nGet-ADUser -Filter {passwordLastSet -lt $old -and Enabled -eq $true} -Properties PasswordLastSet \n \n \n I like to check the operating system of the computers in AD to see if there are any old computers running somewhere long forgotten that need to be decommissioned or upgraded: \n \n get-adcomputer -filter * -properties operatingsystem | Group-Object operatingsystem | Sort-Object count -descending | Select-Object count, name \n \n \n I wanted a few more items checked, and I wanted it to check other domains that trust the one I’m running it in. I also wanted the results in a pretty format for admins to read, so I came up with the following: \n \n #Monthly AD Health Checks\n#Requires -Modules grouppolicy\n#Requires -Modules dhcpserver\n#Requires -Modules activedirectory\n\n<#\n.SYNOPSIS\n Runs some simple checks against AD and generates a report that should be reviewed on a regular basis\n.DESCRIPTION\n This script is designed to be used as a framework for others to modify as they see fit for their environments, not as a one-size-fits-all solution.\n If you would like a more in-depth and sophisticated scan pleast contact Microsoft for an AD assessment.\n This is intended to run as a scheduled task or as part of a SCORCH runbook and has a hardcoded value.\n.NOTES\n Author: Paul Harrison\n#>\n\n$LogFile = '\\\\servername\\share\\path\\ADReport.html'\n\n#Values to define if you want it to email automatically - also uncomment the last line of this file\n<#\n$Body = \"Please review the attached file for AD recommendations. The attached report has shortcuts to each section that are not in the body of the email.`n$HTMLReport\"\n$SubjectLine = \"Recurring AD Report\"\n$ToAddress = @(\"Alice@contoso.com\",\"Bob@contoso.com\",\"Carmet@contoso.com\",\"David@contoso.com\")\n$FromAddress = \"DoNotReply@contoso.com\"\n$SMTPServer = 'mail.contoso.com'\n#>\n\nFunction New-HTMLReport {\n [CmdletBinding()]\n param (\n [parameter(Mandatory = $true)]\n [ValidateNotNullOrEmpty()]\n [string]\n $Title\n )\n \"<H1 id=$('\"'+$($Title.Replace(' ',''))+'\"')>$($title)</H1><br>`n\"\n}\n\nFunction New-HTMLReportSection {\n [CmdletBinding()]\n param (\n [Parameter(Mandatory = $true)]\n [ValidateNotNullOrEmpty()]\n [string]\n $SectionTitle,\n [Parameter()]\n [array]\n $SectionContents = $Null\n )\n $emptyNote = [PSCustomObject]@{message = '[empty]' }\n $MyOut = @()\n $MyOut += \"<br><H2 id=$('\"'+$($SectionTitle.Replace(' ',''))+'\"')>$SectionTitle</H2>`n\"\n If ($SectionContents -eq '' -or $SectionContents -eq $Null) {\n $MyOut += \"<br>$($emptyNote | Select-Object message | ConvertTo-HTML -Fragment)`n\"\n }\n Else {\n $MyOut += \"<br>$($SectionContents | ConvertTo-Html -Fragment)`n\"\n }\n $MyOut\n}\n\n#Find domains to run this report against\n$Trusts = Get-ADTrust -Filter * | Where-Object { $_.Direction -in @([Microsoft.ActiveDirectory.Management.ADTrustDirection]::BiDirectional, [Microsoft.ActiveDirectory.Management.ADTrustDirection]::Inbound) }\n$FoundForestToRunAgainst = $Trusts | ForEach-Object { try { Get-ADForest $_.name; if ($?) { $_.Name } }catch {} }\n$AdditionalDomainsToRunAgainst = ForEach ($Forest in $FoundForestToRunAgainst) {\n ForEach ($domain in $Forest.Domains) {\n try { $Null = Get-ADDomain $domain; if ($?) { domain } }catch {}\n }\n}\n$TargetDomains = [array]$AdditionalDomainsToRunAgainst + (Get-ADDomain).DNSRoot | Select-Object -Unique\n\n[string]$HTMLReport = ''\n\nForEach ($domain in $TargetDomains) {\n\n $HTMLReport += New-HTMLReport -Title \"AD Report for $domain on $((Get-Date).ToShortDateString()) at $((Get-Date).ToLongTimeString())\"\n\n $DomainDN = (Get-ADDomain -Server $domain).distinguishedName\n\n #get objects in the computers container\n $ObjectInComputerContainer = Get-ADObject -SearchBase $('CN=Computers,' + $DomainDN) -Filter { ObjectClass -ne 'container' } -Server $domain\n $HTMLReport += New-HTMLReportSection -SectionTitle \"$domain - Objects in the Computers container\" -SectionContents $($ObjectInComputerContainer | Select-Object name, objectclass, objectguid)\n\n #Get objects in the users container\n $NormalObjectsInUsers = @('DnsAdmins', 'DnsUpdateProxy') #This can be populated with exceptions like built in objects\n $ExtraObjectsInUsersContainer = Get-ADObject -SearchBase $('CN=Users,' + $DomainDN) -Filter { ObjectClass -ne 'container' } -Properties isCriticalSystemObject, samaccountname -Server $domain |\n Where-Object { $_.SamAccountName -notin $NormalObjectsInUsers -and $_.isCriticalSystemObject -ne $true -and $_.SamAccountName -ne $Null -and -not($_.samaccountname.startswith('AAD_')) -and -not($_.samaccountname.startswith('MOL_')) -and ($_.samaccountname -ne 'SUPPORT_388945a0') -and -not($_.samaccountname -like 'CAS_*}*') } \n $HTMLReport += New-HTMLReportSection -SectionTitle \"$domain - Extra objects in the Users container\" -SectionContents $($ExtraObjectsInUsersContainer | Select-Object name, objectclass)\n \n #Find all empty groups\n $emptyGroups = Get-ADGroup -Filter {isCriticalSystemObject -ne $true} -Properties members,isCriticalSystemObject -Server $domain | Where-Object { $($_.members.count) -eq 0 }\n $HTMLReport += New-HTMLReportSection -SectionTitle \"$domain - Empty groups\" -SectionContents $($emptyGroups | Select-Object samaccountname, distinguishedName)\n\n #Find DCs not protected from accidental deletion\n $DCsUnprotectedFromAccidentalDeletion = ((get-addomaincontroller -filter * -Server $domain).computerObjectDN | Get-ADObject -Server $domain -properties ProtectedFromAccidentalDeletion | Where-Object { -not $_.ProtectedFromAccidentalDeletion })\n $HTMLReport += New-HTMLReportSection -SectionTitle \"$domain - DCs not protected from accidental deletion\" -SectionContents $($DCsUnprotectedFromAccidentalDeletion | Select-Object name)\n\n #OUs not protected from accidental deletion\n $OUsUnprotectedFromAccidentalDeletion = ((Get-ADOrganizationalUnit -Filter * -Server $domain).DistinguishedName | Get-ADObject -properties ProtectedFromAccidentalDeletion -Server $domain | Where-Object { -not $_.ProtectedFromAccidentalDeletion })\n $HTMLReport += New-HTMLReportSection -SectionTitle \"$domain - OUs not protected from accidental deletion\" -SectionContents $($OUsUnprotectedFromAccidentalDeletion | Select-Object distinguishedName)\n\n #Find computers with the DHCP server naming convention that are not authorized - comment out this section if you don't want to run against DHCP servers - don't forget to remove the #Requires for DHCPserrver at the top too\n If ($domain -eq (Get-ADDomain).dnsroot) {\n #only works against the domain this machine is on\n $AuthorizedDHCPServers = get-dhcpServerInDC\n $UnauthorizedDHCPServers = (get-adcomputer -filter { samaccountname -like '*pattern*' }).HostName | Where-Object { $_.dnsHostName -notin $AuthorizedDHCPServers.dnsName }\n $HTMLReport += New-HTMLReportSection -SectionTitle \"$domain - Servers with the name of a DHCP server that are not authorized DHCP servers\" -SectionContents $($UnauthorizedDHCPServers | Select-Object name)\n }\n\n #Disabled computer objects\n $DisabledComputerObjects = Get-ADComputer -filter * -Properties whencreated, LastLogonDate -Server $domain | Where-Object { -not $_.Enabled }\n $HTMLReport += New-HTMLReportSection -SectionTitle \"$domain - Disabled computer objects\" -SectionContents $($DisabledComputerObjects | Select-Object name, distinguishedname, whencreated, lastlogondate)\n\n #disabled users\n $DisabledUserObjects = Get-ADUser -filter { Name -notlike 'SystemMailbox*' } -properties whencreated, lastlogondate, memberof -Server $domain | Where-Object { -not $_.enabled }\n $HTMLReport += New-HTMLReportSection -SectionTitle \"$domain - Disabled user objects\" -SectionContents $($DisabledUserObjects | Select-Object samaccountname, enabled, lastlogondate)\n\n #Tombstone info\n $TombstoneLifetime = (Get-ADObject -Identity \"CN=Directory Service,CN=Windows NT,CN=services,$((Get-ADRootDSE -Server $domain).configurationNamingContext)\" -properties tombstoneLifetime -Server $domain).tombstoneLifetime\n $TombstoneDate = (get-Date).AddDays(-1 * $TombstoneLifetime)\n\n #Computer objects with lastlogondate older than tombstone\n $oldComputers = Get-ADComputer -filter { LastLogonDate -lt $TombstoneDate } -properties LastLogonDate -Server $domain\n $HTMLReport += New-HTMLReportSection -SectionTitle \"$domain - Computers with lastLogonDate older than the tombstone - $TombstoneLifetime days ago - $($TombstoneDate.ToShortDateString())\" -SectionContents $($oldComputers | Select-Object name, lastlogondate, distinguishedname)\n\n #Disabled user objects with group membership\n $DisabledUsersWithGroupMembership = $DisabledUserObjects | Where-Object { $_.memberof.count -eq 0 }\n $HTMLReport += New-HTMLReportSection -SectionTitle \"$domain - Disabled users with group membership\" -SectionContents $($DisabledUsersWithGroupMembership | Select-Object name, givenname, surname, enabled, whencreated, lastlogondate, distinguishedname)\n \n #summary of computers by OS\n $ComputersByOS = get-adcomputer -filter * -properties operatingsystem -Server $domain | Group-Object operatingsystem | Sort-Object count -descending | Select-Object count, name\n $HTMLReport += New-HTMLReportSection -SectionTitle \"$domain - Summary of computers by OS\" -SectionContents $ComputersByOS\n\n #users with admincount = 1\n $UsersWithAdminCount1 = Get-ADUser -filter { admincount -eq 1 } -Server $domain\n $HTMLReport += New-HTMLReportSection -SectionTitle \"$domain - Users with admincount = 1\" -SectionContents $($UsersWithAdminCount1 | Select-Object name, givenname, surname)\n\n #Find unlinked GPOs\n $UnlinkedGPOs = Get-GPO -All -Domain $domain | Where-Object { $_ | Get-GPOReport -ReportType XML -Domain $domain | Select-String -NotMatch '<LinksTo>' }\n $HTMLReport += New-HTMLReportSection -SectionTitle \"$domain - Unlinked GPOs\" -SectionContents $($UnlinkedGPOs | Select-Object displayname, creationtime, modificationtime, @{N='WmiFilter';E={$_.wmifilter.Name}})\n\n #Users without a password required\n $UsersWithoutAPasswordRequired = Get-ADUser -Filter { PasswordNotRequired -eq $true } -Properties passwordNotRequired -Server $domain\n $HTMLReport += New-HTMLReportSection -SectionTitle \"$domain - Users without a password required (passwordNotRequired = true)\" -SectionContents $($UsersWithoutAPasswordRequired | Select-Object samaccountname)\n\n #User objects with PasswordNeverExpires = true that are not in a service accounts OU\n $PwdNeverExpires = Get-ADUser -Filter { PasswordNeverExpires -eq $true -and samaccountname -notlike 'HealthMailbox*' } -Properties PasswordNeverExpires -Server $domain | Where-Object { $_.distinguishedName -notlike \"*OU=Service Accounts*,$DomainDN\" }\n $HTMLReport += New-HTMLReportSection -SectionTitle \"$domain - Users with PasswordNeverExpires = true that are not in a service accounts OU\" -SectionContents $($PwdNeverExpires | Select-Object samaccountname, enabled, name, passwordneverexpires, distinguishedname)\n\n #Users with a passwordLastSet over 1 year old\n $old = (Get-Date).AddDays(-365)\n $OldUserObjects = Get-ADUser -Filter { passwordLastSet -lt $old -and samaccountname -notlike 'HealthMailbox*' -and Enabled -eq $true } -Properties PasswordLastSet -Server $domain\n $HTMLReport += New-HTMLReportSection -SectionTitle \"$domain - Enabled User Objects with a password over 1 year old or never set\" -SectionContents $($OldUserObjects | Select-Object samaccountname, enabled, name, passwordneverexpires, distinguishedname)\n\n} #finished collecting data\n\n#generate a table of contents with links to each item\n$HTMLObject = New-Object -ComObject 'HTMLFile'\n$HTMLObject.write([System.Text.Encoding]::Unicode.GetBytes($HTMLReport))\n$AllIDLines = $HTMLObject.all.tags('H2')\n$AllIDs = forEach ($line in $AllIDLines) {\n $start = $line.outerHTML.IndexOf('id=') + 3\n $end = $line.outerHTML.IndexOf('>', $start) - 1\n $end2 = $line.outerHTML.IndexOf('<', $($end + 2))\n [pscustomobject]@{\n ID = $line.outerHTML[$start..$end] -join ('')\n Title = $line.outerHTML[$($end + 2)..$($end2 - 1)] -join ('')\n }\n}\n$TableOfContents = forEach ($ID in $AllIDs) {\n '<a href=#' + $($ID.id) + '>' + $($ID.Title) + '</a><br>'\n}\n\n$HTMLReportWithTOC = $TableOfContents + $HTMLReport\n\n#output \nIf (Test-Path $LogFile) {\n Remove-Item $LogFile -Force\n}\n$HTMLReportWithTOC | Out-File $LogFile -Force\n\n\n\n#Send-MailMessage -Attachments $LogFile -BodyAsHtml $Body -Subject $SubjectLine -To $ToAddress -From $FromAddress -SmtpServer $SMTPServer \n \n \n \n Some sample output: \n \n \n More elegant formatting could have been done with other PowerShell modules or more time, but my customer wanted to review any PowerShell modules before loading them into the environment, so this quick and simple way worked for my purposes. I wanted the code to be easy to modify, so now if the customer wants to add one more item to monitor regularly, they simply add 2-3 lines of code and they get an automatic report. I’ve deployed this as a System Center Orchestrator runbook if it is available or as a scheduled task in other networks. \n Regular maintenance and monitoring of Active Directory are important to maintain security and proper configuration. This script can help even in environments without fancy monitoring tools like SCOM. \n Have fun scripting! \n \n \n Additional reading: \n \n A copy of the code: https://github.com/PaulHCode/RecurringADChecks/blob/main/RecurringADChecks.ps1 \n Active Directory module for PowerShell: https://docs.microsoft.com/en-us/powershell/module/activedirectory/ \n On Demand Assessments: https://serviceshub.microsoft.com/assessments/ \n Setting up On Demand Active Directory Assessments: https://www.microsoft.com/en-us/videoplayer/embed/RWwTzK \n \n \n Setting up On Demand Active Directory Security Assessments: https://www.microsoft.com/en-us/videoplayer/embed/RWwWaK \n Offline Assessment for Active Directory: OfflinePrereq (windows.net) \n Offline Assessment for Active Directory Security: Pre-Reqs for Active Directory Security (windows.net) \n Offline Assessments: Purchased Offline assessments are now available on the Services Hub | Microsoft Docs \n \n ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"19911","kudosSumWeight":17,"repliesCount":6,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDE","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMDQ3MjU4LTMzNjIxNWlGMzM5QjYwMjZFMUNDMzBF?revision=2\"}"}}],"totalCount":1,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"coverImage":null,"coverImageProperties":{"__typename":"CoverImageProperties","style":"STANDARD","titlePosition":"BOTTOM","altText":""}},"Conversation:conversation:4066848":{"__typename":"Conversation","id":"conversation:4066848","topic":{"__typename":"BlogTopicMessage","uid":4066848},"lastPostingActivityTime":"2024-03-11T03:00:00.026-07:00","solved":false},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDY2ODQ4LTU1NDkyOWlDNTU0ODA1Q0U3MjRDOUJE?revision=3\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDY2ODQ4LTU1NDkyOWlDNTU0ODA1Q0U3MjRDOUJE?revision=3","title":"PaulHarrison_0-1708885661468.png","associationType":"BODY","width":975,"height":49,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDY2ODQ4LTU1NDkzMGlCRjMwRjFGREEwRENDMDA0?revision=3\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDY2ODQ4LTU1NDkzMGlCRjMwRjFGREEwRENDMDA0?revision=3","title":"PaulHarrison_1-1708885679858.png","associationType":"BODY","width":975,"height":595,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDY2ODQ4LTU1NDkzMWlDNzk4OTcxNDRBOTQ1RUZG?revision=3\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDY2ODQ4LTU1NDkzMWlDNzk4OTcxNDRBOTQ1RUZG?revision=3","title":"PaulHarrison_2-1708885702455.png","associationType":"BODY","width":592,"height":563,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDY2ODQ4LTU1NDkzMmk3QkFDRUNDMUIyRjg0OTRC?revision=3\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDY2ODQ4LTU1NDkzMmk3QkFDRUNDMUIyRjg0OTRC?revision=3","title":"PaulHarrison_3-1708885800113.png","associationType":"BODY","width":975,"height":128,"altText":null},"BlogTopicMessage:message:4066848":{"__typename":"BlogTopicMessage","subject":"Azure PowerShell Tips and Tricks","conversation":{"__ref":"Conversation:conversation:4066848"},"id":"message:4066848","revisionNum":3,"uid":4066848,"depth":0,"board":{"__ref":"Blog:board:CoreInfrastructureandSecurityBlog"},"author":{"__ref":"User:user:399999"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":" Tips and tricks for using PowerShell and REST APIs in Azure. ","introduction":"","metrics":{"__typename":"MessageMetrics","views":7729},"postTime":"2024-03-11T03:00:00.026-07:00","lastPublishTime":"2024-03-11T03:00:00.026-07:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" \n I’ve spent most of my days lately writing PowerShell and using REST APIs as part of my work in Azure. When I’m screen sharing with colleagues, I frequently learn different and better ways to do my work. This post is to share with you several tips and tricks I’ve shared with my colleagues, and I hope helps you shave minutes or hours off of your work. \n \n Use ConvertTo-JSON to more easily read output. \n When I’m working with a new object in Azure I often don’t know where the information I care about is actually found in output. PowerShell makes it easy to navigate through objects, however it isn’t easy to get an overview of all properties available if they’re nested 5 levels deep. I like to use ConvertTo-JSON to help me get a general understanding for a new object and which properties are available and how to find them. \n For example, if I wasn’t familiar with storage accounts, I might create a test one to look at, or look at others in an existing environment like this: \n $SAs = Get-AzStorageAccount \n $SAs[0] \n That gives me some basic output, but not the details as seen below. \n \n It is common to use Format-List to provide more verbose output as seen here. \n \n Unfortunately, it is common in many resources I’ve worked with in Azure for the information I care about to be buried several layers deep, like in a child property of Sku. \n Fortunately, an easy way to get a quick view of an object is to use ConvertTo-JSON. This converts the whole object into JSON for easy viewing, especially if you have a good viewer like VSCode. For example, I would run the following, then paste the results into VSCode for easy viewing. \n $SAs[0] | ConvertTo-Json | Set-Clipboard \n \n With the object in VSCode it is much easier for me to then run a search for the property I’m interested in. For example, If I wanted to find where it was telling me that it was using LRS, I could just search for “LRS” and immediately see that I could later reference that in code as $SAs[0].Sku.Name. \n \n Use Group-Object to summarize information. \n \n I often analyze Azure tenants with many resources. A short query in PowerShell can make certain analysis take only seconds. Someone wanted a list of every resource type deployed to the environment. \n \n \n Get-AzResource | group type | select count, name \n \n I was then told he actually wanted a list of every resource type deployed, but broken down by subscription. \n \n get-azresource | group subscriptionid, type | select count,name \n \n Group-Object certainly makes life easier. \n \n Use named expressions to quickly get useful information that wasn’t returned exactly as you want. \n We wanted to validate our storage accounts were all properly configured with the SKU we expected. We couldn’t just group on the Sku Name though because it wasn’t a top-level property returned. I am frequently given the information I want, just not exactly how I want it. \n \n Get-AzStorageAccount | select @{N='SkuName';e={$_.Sku.Name}} | group skuname | select count,name \n \n Count Name \n ----- ---- \n 1 Standard_GRS \n 8 Standard_LRS \n \n Oh no, we found a few using LRS, which ones are they: \n (Get-AzStorageAccount | select id,@{N='SkuName';e={$_.Sku.Name}} | group skuname | where{$_.name -eq 'Standard_LRS'}).group.id \n \n Named expressions are perfect for making the data just the way I like it. \n \n Using a hash table makes lookups faster and easier. \n \n I’ll frequently get back resource data that includes a resource ID, but humans that I send information to like to see the subscription name, not an ID. If I’m looking up thousands of resources then I don’t want to do thousands of queries to lookup a subscription either, that just takes too long. Hash tables are my friend to solve this problem. \n \n I first put every subscription ID and name into a hashtable, then I can do a lookup anytime I like to get pretty output. \n $subs = Get-AzSubscription | %{@{$_.id = $_.Name}} \n $allVMs = Get-AzVM \n $allVMs | select location, @{n='sub';e={$_.id.split('/')[2]}} | select location, @{n='subName';E={$subs.\"$($_.sub)\"}} | group location, subname | select count,name \n \n Count Name \n 78 eastus, Subscription0 \n 2 eastus, Subscription1 \n 3 eastus, Subscription2 \n 2 eastus, Subscription3 \n 94 southeastasia, Subscription4 \n 50 westeurope, Subscription5 \n 1 westus, Subscription6 \n 100 westus2, Subscription7 \n \n Use Get-AzProviderOperation to determine which permissions are available for a particular provider. \n \n Setting the permissions to the minimum required, and not more for your Entra ID identities is very important. I generally know what permissions I want to assign to an identity, but don’t always know what it is called which is where Get-AzProviderOperation comes in. \n \n When I wanted to grant access to a key vault, I queried to find exactly which permission I should use. I wanted to make sure that the ID could read metadata, but not the actual secrets. \n Get-AzProviderOperation \"Microsoft.KeyVault/vaults/secrets/*\" | ft \n \n After looking at this output I was quickly able to determine that I needed to request “Microsoft.KeyVault/vaults/secrets/readMetadata/action” for my identity. \n \n I hope you were able to find a useful tidbit to help you in your work. \n \n Have fun scripting! \n \n References: \n \n https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/convertto-json?view=powershell-7.4 \n https://techcommunity.microsoft.com/t5/core-infrastructure-and-security/parsing-json-with-powershell/ba-p/2768721 \n https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_hash_tables?view=powershell-7.4 \n https://learn.microsoft.com/en-us/powershell/module/az.resources/get-azprovideroperation?view=azps-11.2.0 \n https://techcommunity.microsoft.com/t5/core-infrastructure-and-security/running-powershell-against-all-azure-subscriptions/ba-p/2347432 \n https://learn.microsoft.com/en-us/azure/azure-monitor/logs/data-collector-api?tabs=powershell \n ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"6603","kudosSumWeight":5,"repliesCount":0,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDE","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDY2ODQ4LTU1NDkyOWlDNTU0ODA1Q0U3MjRDOUJE?revision=3\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDI","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDY2ODQ4LTU1NDkzMGlCRjMwRjFGREEwRENDMDA0?revision=3\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDM","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDY2ODQ4LTU1NDkzMWlDNzk4OTcxNDRBOTQ1RUZG?revision=3\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDQ","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDY2ODQ4LTU1NDkzMmk3QkFDRUNDMUIyRjg0OTRC?revision=3\"}"}}],"totalCount":4,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"coverImage":null,"coverImageProperties":{"__typename":"CoverImageProperties","style":"STANDARD","titlePosition":"BOTTOM","altText":""}},"Conversation:conversation:2347432":{"__typename":"Conversation","id":"conversation:2347432","topic":{"__typename":"BlogTopicMessage","uid":2347432},"lastPostingActivityTime":"2023-10-21T22:53:05.307-07:00","solved":false},"BlogTopicMessage:message:2347432":{"__typename":"BlogTopicMessage","subject":"Running PowerShell Against All Azure Subscriptions","conversation":{"__ref":"Conversation:conversation:2347432"},"id":"message:2347432","revisionNum":4,"uid":2347432,"depth":0,"board":{"__ref":"Blog:board:CoreInfrastructureandSecurityBlog"},"author":{"__ref":"User:user:399999"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":" How to run PowerShell on all of your Azure subscriptions at once. ","introduction":"","metrics":{"__typename":"MessageMetrics","views":10728},"postTime":"2021-05-13T00:00:00.046-07:00","lastPublishTime":"2021-05-14T06:34:54.133-07:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" \n Q: How do I run my PowerShell command against all my Azure subscriptions? \n A: Easy – Use the cmdlet I wrote when I ran into the same problem. \n \n When you go from one Azure subscription to two, three, or hundreds it is no longer trivial to run a single command against all your subscriptions in PowerShell. I was working with one subscription that quickly expanded to three then soon more than a dozen. Opening new PowerShell hosts for each environment and switching between them was too much work. I needed an easy way to assess everything across all my subscriptions. My solution was to write Invoke-AzureCommand. Invoke-AzureCommand allows you to run a script block against every subscription easily. To use it install AzureHelper, put your code in a script block, and run Invoke-AzureCommand to do the repetitive work of cycling the script block across all your subscriptions. \n \n Disclaimer: The sample scripts are not supported under any Microsoft standard support program or service. The sample scripts are provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages. \n \n 1. Install AzureHelper \n To get started, install the AzureHelper module using the following command: \n \n \n Install-Module AzureHelper \n \n \n If you prefer, you could also download it from GitHub here: www.GitHub.com/PaulHCode/AzureHelper \n \n 2. Put your code in a script block \n Put whatever commands you want to run against all of your subscriptions into a script block. If you are new to script blocks check out more information on script blocks here. \n For example, I want to find all Azure Disks that are larger than 512 GB across my subscriptions. To find these I put the following script block together. \n \n \n $DiskScriptBlock = {Get-AzDisk | Where{$_.DiskSizeGB -gt 512}} \n \n \n \n 3. Run your script block against all subscriptions \n Running the script block against all subscriptions is as easy as the example below. \n \n \n Invoke-AzureCommand -AllSubscriptions -ScriptBlock $DiskScriptBlock | FT ResourceGroupName, Name, DiskSizeGB \n \n \n This example gives the output from every subscription, but if we have the same resource group name in multiple subscriptions then it isn’t clear which subscription contains the resource. To fix that we use a named expression to include the name of the subscription as seen in the following example. \n \n Are you concerned about deallocated VMs sitting around that you don’t need anymore? Use the following: \n \n \n $MyScriptBlock = {get-azvm -Status | Where{$_.PowerState -eq 'VM deallocated'} | Select Name, ResourceGroupName, @{N='Subscription';E={(Get-AzContext).Subscription.Name}}} \n\nInvoke-AzureCommand -ScriptBlock $MyScriptBlock -AllSubscriptions \n \n \n \n Okay, that sure makes a quick query easier but what if I want to do something a little more complex in my script block that needs arguments passed in? I’m glad you asked. Invoke-AzureCommand also supports passing an array of arguments into your scriptblock as seen in the example here. \n \n \n $ArgumentList = @() \n$ArgumentList+=512 # The first parameter is the minimum disk size \n$ArgumentList+=\"westus2\" # The second parameter is the Azure region to search \n\n$BetterDiskScriptBlock = { \n param($disksize, $region) \n Get-AzDisk | Where{$_.DiskSizeGB -gt $disksize} | Where{$_.Location -eq $region} \n} \n\nInvoke-AzureCommand -ScriptBlock $BetterDiskScriptBlock -AllSubscriptions -ArgumentList $ArgumentList \n \n \n \n You can make this example shorter by passing the arguments directly to Invoke-AzureCommand like this. \n \n \n Invoke-AzureCommand -ScriptBlock $BetterDiskScriptBlock -AllSubscriptions -ArgumentList 512,\"westus2\" \n \n \n \n Have fun scripting! ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"5195","kudosSumWeight":5,"repliesCount":1,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"coverImage":null,"coverImageProperties":{"__typename":"CoverImageProperties","style":"STANDARD","titlePosition":"BOTTOM","altText":""}},"Conversation:conversation:3882970":{"__typename":"Conversation","id":"conversation:3882970","topic":{"__typename":"BlogTopicMessage","uid":3882970},"lastPostingActivityTime":"2023-07-27T06:38:58.093-07:00","solved":false},"BlogTopicMessage:message:3882970":{"__typename":"BlogTopicMessage","subject":"Q: My laptop stops charging sometimes, what do I do?","conversation":{"__ref":"Conversation:conversation:3882970"},"id":"message:3882970","revisionNum":1,"uid":3882970,"depth":0,"board":{"__ref":"Blog:board:CoreInfrastructureandSecurityBlog"},"author":{"__ref":"User:user:399999"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":" A: If you’re lucky then you can wiggle the power cable to get it to charge again. Here is a script to tell you when to wiggle. ","introduction":"","metrics":{"__typename":"MessageMetrics","views":2763},"postTime":"2023-07-27T03:00:00.032-07:00","lastPublishTime":"2023-07-27T03:00:00.032-07:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" Old computers often work fine but they develop trouble charging. I had my laptop in a docking station today as it has been all week, but it ran out of power and turned off in the middle of a meeting. I immediately scrambled for my personal smart phone and got back into the meeting. My personal cell phone was already connected through Intune to my company and had Teams already installed and configured so it was quick and easy to recover, but hard to present what had just been lost on my laptop. \n Fortunately, my colleagues were understanding but I don’t want my laptop powering off unexpectedly when I just need to wiggle the cable to keep it going. Like most problems, this one can be solved with a script. This example shows how to leverage PowerShell in your daily life without going out and writing big complex scripts. \n Disclaimer \n The sample scripts are not supported under any Microsoft standard support program or service. The sample scripts are provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages. \n I didn’t just happen to know how to check battery status from PowerShell so I Binged it to find the WMI object here https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-battery. Then I ran the following to see what my battery looked like. \n Get-WmiObject win32_battery \n \n I examined the output and quickly learned my laptop has 2 batteries. I decided I wanted to be alerted if either battery was below 50% or was considered low or critical. If that was the case, then give me a popup so that I know that I need to wiggle my cable. \n $batteryStatus = Get-WmiObject win32_battery\n\n$badStatus = @(4,5,8,9)\n\n$minChargeRemaining = 50\n\n\n\nForEach($battery in $batteryStatus){\n\n If($battery.BatteryStatus -in $badStatus -or $battery.EstimatedChargeRemaining -lt $minChargeRemaining){\n\n [System.Windows.MessageBox]::Show(\"Your computer has an estimated $($battery.EstimatedChargeRemaining) minutes remaining. Please wiggle the charging cable.\")\n\n }\n\n}\n\n \n Yay! Now when I run that script it will alert me if my battery is low but not bother me if the battery is fine. I could also just look at my battery icon every 5 minutes, but that is easy to forget when I’m working so I put it in a loop. Now my computer will let me know if I need to give the power cable a little wiggle. \n \n The PowerShell script is available at https://github.com/PaulHCode/PowerWiggler \n You might say that my workaround is a bit kludgy and not a permanent solution. You’re right, but it is enough to keep the laptop in service until I can get a new one. I like perfect permanent solutions but sometimes we need a stop-gap measure and in this case, PowerShell is my duct tape to keep everything working for just a little while longer. \n \n Have fun scripting! \n \n References: \n \n Battery Status: https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-battery \n Repository: https://github.com/PaulHCode/BatteryReminder \n ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"3704","kudosSumWeight":2,"repliesCount":1,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"coverImage":null,"coverImageProperties":{"__typename":"CoverImageProperties","style":"STANDARD","titlePosition":"BOTTOM","altText":""}},"Conversation:conversation:3859133":{"__typename":"Conversation","id":"conversation:3859133","topic":{"__typename":"BlogTopicMessage","uid":3859133},"lastPostingActivityTime":"2023-07-10T03:00:00.030-07:00","solved":false},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODU5MTMzLTQ4MzkxOGkyREEyRDcyQjc5OTQ4MzlG?revision=4\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODU5MTMzLTQ4MzkxOGkyREEyRDcyQjc5OTQ4MzlG?revision=4","title":"PolicyExemptionsSS0.png","associationType":"BODY","width":2866,"height":595,"altText":null},"BlogTopicMessage:message:3859133":{"__typename":"BlogTopicMessage","subject":"Azure Policy Exemption Validation","conversation":{"__ref":"Conversation:conversation:3859133"},"id":"message:3859133","revisionNum":4,"uid":3859133,"depth":0,"board":{"__ref":"Blog:board:CoreInfrastructureandSecurityBlog"},"author":{"__ref":"User:user:399999"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":" Q: I’m working on Azure Policy for a large environment, how do I do some basic validation that I didn’t make common mistakes? \n A: There are a few ways I’ve validated my environment using PowerShell that I’ll walk through here. ","introduction":"","metrics":{"__typename":"MessageMetrics","views":8736},"postTime":"2023-07-10T03:00:00.030-07:00","lastPublishTime":"2023-07-10T03:00:00.030-07:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" Q: I’m working on Azure Policy for a large environment, how do I do some basic validation that I didn’t make common mistakes? \n A: There are a few ways I’ve validated my environment using PowerShell that I’ll walk through here. \n \n I enjoy using Azure Policy to enforce compliance and prevent mistakes that could make my clients non-compliant and cause all sorts of security problems. My clients often like to follow stricter standards than required by some regulations, while having more relaxed special exceptions to regulation for other resources. These special exceptions have the risk accepted and have exceptions logged as waivers. There are still other items where the client has met the compliance objective through different ways than Azure is able to measure, so we put in an exception stating that the issue has been mitigated. Azure Policy and Defender for Cloud make this process far less painful than it was before the cloud, however how do you know that someone on your team didn’t make a mistake while logging an exemption? People will always make mistakes, but I like to do some basic analysis through some scripting to validate that what my team did is mistake-free, and that regulators won’t find any paperwork errors. \n Before we get into good fun code, we have to see what the lawyers have for us. \n Disclaimer \n The sample scripts are not supported under any Microsoft standard support program or service. The sample scripts are provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages. \n \n To analyze all exemptions and find problematic ones, we first need to collect all the exemptions. It is easy to have dozens of subscriptions across many tenants, and running a script in each one gets to be a pain. Fortunately, I documented an easy way to execute code against all subscriptions in a blog a couple of years ago here. Since I was going to be scanning several different environments, I made my life easier and wrote a cmdlet available in a module here and here for finding all policy exemptions. \n \n To get all policy exemptions I simply run: \n \n $allExemptions = Get-AHAllPolicyExemptions \n \n If you don’t get data, or not much data back, then make sure you have permissions to query all subscriptions and management groups of concern. You may need to PIM into additional roles. If you only have permission to some subscriptions but not others, then you will get a warning when running this command but it will collect whatever you have permission to. \n Now that I have all exceptions, I can look through them to find anomalous ones. \n \n To track down which exemptions are unusual, I decided on the following criteria. This is what worked for me, but you can modify these according to your needs. \n \n Exempt an entire policy initiative instead of just one or a few policies – a resource may have a special exemption like having a storage account publicly accessible and have an exemption in place for it, however it should only be exempt from that single policy, not all regulations for your industry. If policies are applied incorrectly, then exemptions can be put in place to exclude a resource from all regulations in an initiative. \n Exemptions that do not expire – exemptions should be validated at regular intervals to validate that they are still correct and necessary, so any exemption without an expiration warrants investigation. \n Exemptions without a description – Exemptions should have a meaningful explanation of why it was put in place. For a waiver, there should be a description of why the risk was accepted; for a mitigation, the description should explain how the threat was mitigated. If there is no description, then it is unclear to auditors, so I want these to be re-visited and fixed. \n \n Now that we have all exemptions stored in a variable and we know what to look for, we can output some pretty data. \n List all exemptions where an entire initiative is excluded instead of individual policies: \n \n $allExemptions | Where{$_.Properties.PolicyDefinitionReferenceIds.count -eq 0} \n \n I want to make it prettier and easier to work with the output though, so here is a prettier version: \n \n $allSubs = Get-AzSubscription | %{@{$_.SubscriptionId = $_.Name}} #Hashtable of subscriptions \n$allExemptions | Where{$_.Properties.PolicyDefinitionReferenceIds.count -eq 0} | Select Name, SubscriptionId -ExpandProperty Properties | Select DisplayName, Description, Name, @{N='NumberOfPoliciesExempted';E={$_.PolicyDefinitionReferenceIds.count}}, ExemptionCategory, @{N='SubscriptionName';E={$allSubs.$($_.SubscriptionId)}} | FT \n \n The names of some exemptions are pseudo-random strings, so why do I output them? I’m lazy, when I want to look at an exemption in the portal, I want it to be easy to find, so I copy the Name into the search field which narrows down hundreds of exemptions to a single exemption. This is especially helpful if you have many exemptions with the same display name. \n \n \n \n List all exemptions that do not expire: \n \n $allExemptions | Where{$Null -eq $_.Properties.ExpiresOn} \n \n Yay, that is pretty quick, now we can add the same stuff to make it prettier. \n \n $allExemptions | Where{$Null -eq $_.Properties.ExpiresOn} | Select Name, SubscriptionId -ExpandProperty Properties | Select DisplayName, Description, Name, @{N='NumberOfPoliciesExempted';E={$_.PolicyDefinitionReferenceIds.count}}, ExemptionCategory, @{N='SubscriptionName';E={$allSubs.$($_.SubscriptionId)}} | FT \n \n List all exemptions without a description: \n \n $allExemptions | Where{$Null -eq $_.Properties.Description} \n \n Again, I’ll pretty it up: \n \n $allExemptions | Where{$Null -eq $_.Properties.Description} | Select Name, SubscriptionId -ExpandProperty Properties | Select DisplayName, Description, Name, @{N='NumberOfPoliciesExempted';E={$_.PolicyDefinitionReferenceIds.count}}, ExemptionCategory, @{N='SubscriptionName';E={$allSubs.$($_.SubscriptionId)}} | FT \n \n Another option is to list all exemptions sorted by how many policies are exempted in each exemption. Exemptions listed as 0 policies exempted means all policies are exempted, a non-zero number is how many policies are exempted. To understand why 0 means everything, you can read more about it here. \n \n $allExemptions | Select Name, SubscriptionId -ExpandProperty Properties | Select DisplayName, Description, Name, @{N='NumberOfPoliciesExempted';E={$_.PolicyDefinitionReferenceIds.count}}, ExemptionCategory, @{N='SubscriptionName';E={$allSubs.$($_.SubscriptionId)}} | sort NumberOfPoliciesExempted | FT \n \n I hope you have enjoyed a glimpse into the kind of fun only attainable with fine attention to regulatory compliance. \n \n Have fun scripting! \n \n References: \n \n Azure Policy Exemption Structure: https://learn.microsoft.com/en-us/azure/governance/policy/concepts/exemption-structure \n More on parsing JSON with PowerShell: https://techcommunity.microsoft.com/t5/core-infrastructure-and-security/parsing-json-with-powershell/ba-p/2768721 \n Azure Helper GitHub: https://github.com/PaulHCode/AzureHelper \n Azure Helper PowerShell Gallery: https://www.powershellgallery.com/packages/AzureHelper/ \n ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"8222","kudosSumWeight":1,"repliesCount":0,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDE","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zODU5MTMzLTQ4MzkxOGkyREEyRDcyQjc5OTQ4MzlG?revision=4\"}"}}],"totalCount":1,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"coverImage":null,"coverImageProperties":{"__typename":"CoverImageProperties","style":"STANDARD","titlePosition":"BOTTOM","altText":""}},"Conversation:conversation:2768721":{"__typename":"Conversation","id":"conversation:2768721","topic":{"__typename":"BlogTopicMessage","uid":2768721},"lastPostingActivityTime":"2023-03-29T10:03:36.254-07:00","solved":false},"BlogTopicMessage:message:2768721":{"__typename":"BlogTopicMessage","subject":"Parsing JSON with PowerShell","conversation":{"__ref":"Conversation:conversation:2768721"},"id":"message:2768721","revisionNum":8,"uid":2768721,"depth":0,"board":{"__ref":"Blog:board:CoreInfrastructureandSecurityBlog"},"author":{"__ref":"User:user:399999"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":" How to parse JSON in PowerShell in any version of PowerShell. ","introduction":"","metrics":{"__typename":"MessageMetrics","views":193366},"postTime":"2021-09-20T14:25:47.945-07:00","lastPublishTime":"2021-09-21T10:14:57.829-07:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" Q: I try to parse my JSON with the handy dandy “ConvertFrom-JSON” cmdlet but it only works in PowerShell 7, not in my good old PowerShell 5.1. How do I get it to work everywhere? \n \n A: PS 7 parses JSON a little differently than PS 5.1 by ignoring comments and accepting less than ideal JSON so you need to clean up your JSON for PS 5.1. Use the function below to do it for you. \n \n Java Script Object Notation (JSON) is a popular format these days for sending and receiving data with Azure. JSON is used for sending and receiving data using Azure REST API, deploying resources to Azure using ARM templates, configure governance in Azure using Azure Policy, and much more. PowerShell is a great tool for creating and modifying JSON. PowerShell 7.1 is my preferred solution since it has additional capabilities however sometimes we still need good old PS 5.1 so it is nice to be able to accomplish anything in either version. \n \n Disclaimer: The sample scripts are not supported under any Microsoft standard support program or service. The sample scripts are provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages. \n \n First, here is a sample file I’ll use for the example or you can download it from here. \n \n \n \n { \n \"Accounts\": { \n \"Users\": [ \n { \n \"jdoe\": { \n \"givenName\": \"John\", //Out on leave this month \n \"surname\": \"Doe\", \n \"department\": \"Finance\" \n }, \n \"jdoe2\": { \n \"givenName\": \"Jane\", //Department head \n \"surname\": \"Doe\", \n \"department\": \"Marketing\" \n }, \n \"asmith\": { \n \"givenName\": \"Alice\", /* Sits in the corner office */ \n \"surname\": \"Smith\", \n \"department\": \"IT\" \n } \n } \n ] \n } \n} \n \n \n \n \n Alice got promoted so we need to change her department to Senior Leadership. PowerShell makes it easy to modify JSON by converting JSON to a PSCustomObject. The object can then be modified easily like any other object. The object can then be exported back out using ConvertTo-Json. \n \n \n \n $myJson = Get-Content .\\test.json -Raw | ConvertFrom-Json \n$myJson.Accounts.Users.asmith.department = \"Senior Leadership\" \n$myJson | ConvertTo-Json -Depth 4 | Out-File .\\test.json \n \n \n \n \n This gives a test.json file that accomplished exactly what we wanted: \n \n \n \n { \n \"Accounts\": { \n \"Users\": [ \n { \n \"jdoe\": { \n \"givenName\": \"John\", \n \"surname\": \"Doe\", \n \"department\": \"Finance\" \n }, \n \"jdoe2\": { \n \"givenName\": \"Jane\", \n \"surname\": \"Doe\", \n \"department\": \"Marketing\" \n }, \n \"asmith\": { \n \"givenName\": \"Alice\", \n \"surname\": \"Smith\", \n \"department\": \"Senior Leadership\" \n } \n } \n ] \n } \n} \n \n \n \n \n Now if we’re on a computer without PowerShell 7.1 we try to run the same command in PowerShell 5.1 but it fails! \n \n \n \n PS> $a = gc .\\test.json -Raw | ConvertFrom-Json \nConvertFrom-Json : Invalid object passed in, ':' or '}' expected. (17161):{ \n<the entire contents of the json file listed here> \n} \nAt line:1 char:28 \n+ $a = gc .\\test.json -Raw | ConvertFrom-Json \n+ ~~~~~~~~~~~~~~~~ \n + CategoryInfo : NotSpecified: (:) [ConvertFrom-Json], ArgumentException \n + FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.ConvertFromJsonCommand \n \n \n \n \n Comments will prevent ConvertFrom-Json from working properly in PowerShell 5.1. I like to use this simple function to fix my JSON for me. \n \n \n \n Function Remove-Comments{ \n param( \n [CmdletBinding()] \n [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true,Position=0)] \n [string] \n [ValidateScript({test-path $_})] \n $File \n ) \n $CComments = \"(?s)/\\\\*.*?\\\\*/\" \n $content = Get-Content $File -Raw \n [regex]::Replace($content,$CComments,\"\") | Out-File $File -Force \n} \n \n \n \n \n Simply run the following to fix the json file: \n \n \n \n Remove-Comments .\\test.json \n \n \n \n \n Now test.json file looks like this: \n \n \n \n { \n \"Accounts\": { \n \"Users\": [ \n { \n \"jdoe\": { \n \"givenName\": \"John\", \n \"surname\": \"Doe\", \n \"department\": \"Finance\" \n }, \n \"jdoe2\": { \n \"givenName\": \"Jane\", \n \"surname\": \"Doe\", \n \"department\": \"Marketing\" \n }, \n \"asmith\": { \n \"givenName\": \"Alice\", \n \"surname\": \"Smith\", \n \"department\": \"IT\" \n } \n } \n ] \n } \n} \n \n \n \n \n Now that the comments are gone the JSON can be converted into a PSCustomObject using the following just like in PS7: \n \n \n \n $myJson = Get-Content .\\test.json -Raw | ConvertFrom-Json \n \n \n \n \n PowerShell is a great tool to use for manipulating JSON which is used throughout Azure. \n Have fun scripting! \n \n Additional reading: \n \n 7.1: ConvertFrom-Json (Microsoft.PowerShell.Utility) - PowerShell | Microsoft Docs \n 5.1: ConvertFrom-Json (Microsoft.PowerShell.Utility) - PowerShell | Microsoft Docs \n 7.1: ConvertTo-Json (Microsoft.PowerShell.Utility) - PowerShell | Microsoft Docs \n 5.1: ConvertTo-Json (Microsoft.PowerShell.Utility) - PowerShell | Microsoft Docs \n \n \n 7.1: Test-Json (Microsoft.PowerShell.Utility) - PowerShell | Microsoft Docs \n Azure REST API reference documentation | Microsoft Docs \n Overview of Azure Policy - Azure Policy | Microsoft Docs \n ARM template documentation | Microsoft Docs \n ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"7443","kudosSumWeight":3,"repliesCount":1,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"coverImage":null,"coverImageProperties":{"__typename":"CoverImageProperties","style":"STANDARD","titlePosition":"BOTTOM","altText":""}},"Conversation:conversation:3679869":{"__typename":"Conversation","id":"conversation:3679869","topic":{"__typename":"BlogTopicMessage","uid":3679869},"lastPostingActivityTime":"2023-03-16T16:35:44.960-07:00","solved":false},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjc5ODY5LTQxOTkyNWkxMEUzNEVDMkNCNUU3NjUx?revision=9\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjc5ODY5LTQxOTkyNWkxMEUzNEVDMkNCNUU3NjUx?revision=9","title":"20211108-blog.png","associationType":"TEASER","width":1178,"height":244,"altText":null},"BlogTopicMessage:message:3679869":{"__typename":"BlogTopicMessage","subject":"How Do I Know If My AD Environment Is Impacted By The November 8th 2022 Patch?","conversation":{"__ref":"Conversation:conversation:3679869"},"id":"message:3679869","revisionNum":9,"uid":3679869,"depth":0,"board":{"__ref":"Blog:board:CoreInfrastructureandSecurityBlog"},"author":{"__ref":"User:user:399999"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":" \n A quick post to help you navigate the Kerberos on domain controllers issues stemming from the November 8, 2022 update ","introduction":"","metrics":{"__typename":"MessageMetrics","views":267193},"postTime":"2022-11-18T10:42:15.641-08:00","lastPublishTime":"2023-03-16T16:35:44.960-07:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" \n Q: How can I determine if objects in my AD environment are impacted by the November 8 th 2022 patch? \n A: Use a couple of queries I wrote specifically for that purpose. \n \n November 8 th , 2022 brought us a patch that caused some clients extra headaches because when the patch is installed on Domain Controllers Kerberos authentication can break for AD objects. If you want details about the problem patches or the out of band patch to replace the problem patches check the links below. Now that a non-breaking patch has been released this extra investigation isn’t necessary but may help you develop useful techniques for the future. This is how I helped clients immediately investigate if their environments would be impacted by the patch by using a little PowerShell. \n For information about the out of band patch: \n \n Win2022: November 17, 2022 Non-security update (KB5021656) Out-of-band - Microsoft Support \n Win2019: November 17, 2022—KB5021655 (OS Build 17763.3653) Out-of-band - Microsoft Support \n Win2016: November 17, 2022—KB5021654 (OS Build 14393.5502) Out-of-band - Microsoft Support \n Win2012 R2: KB5021653: Out-of-band update for Windows Server 2012 R2: November 17, 2022 - Microsoft Support \n Win2012: KB5021652: Out-of-band update for Windows Server 2012: November 17, 2022 - Microsoft Support \n Win2008 SP2: KB5021657: Out-of-band update for Windows Server 2008 SP2: November 17, 2022 - Microsoft Support \n Win2008 R2 (SP1): KB5021651: Out-of-band update for Windows Server 2008 R2: November 18, 2022 - Microsoft Support \n \n \n For information on the problematic patch that we’re addressing in the investigation for the rest of the article: \n \n Server 2022: November 8, 2022—KB5019081 (OS Build 20348.1249) - Microsoft Support \n Windows 11 21H2: November 8, 2022—KB5019961 (OS Build 22000.1219) - Microsoft Support \n Windows 10 20H2 +: November 8, 2022—KB5019959 (OS Builds 19042.2251, 19043.2251, 19044.2251, and 19045.2251) - Microsoft Support \n Server 2019: November 8, 2022—KB5019966 (OS Build 17763.3650) - Microsoft Support \n Server 2016: November 8, 2022—KB5019964 (OS Build 14393.5501) - Microsoft Support \n Server 2012 R2: November 8, 2022—KB5020023 (Monthly Rollup) - Microsoft Support \n Server 2012: November 8, 2022—KB5020009 (Monthly Rollup) - Microsoft Support \n \n \n I’m almost ready to start writing some PowerShell, first let’s make the lawyers happy. \n \n Disclaimer \n The sample scripts are not supported under any Microsoft standard support program or service. The sample scripts are provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages. \n \n For a quick answer without me rambling anymore just grab code here or run the following command to find impacted objects: \n \n \n \n Get-ADObject -Filter * -Properties msDS-SupportedEncryptionTypes | `\nselect name,objectClass,'msDS-SupportedEncryptionTypes', @{N='EncryptionTypes';E={Get-ETypeDefinition -msDSSupportedEncryptionTypes ($_.'msDS-SupportedEncryptionTypes')}}, @{N='EncryptionTypesAsString';E={Get-ETypeDefinition -msDSSupportedEncryptionTypes ($_.'msDS-SupportedEncryptionTypes') -AsString}} | `\nselect name,objectClass,EncryptionTypes,@{N='HasRC4OrIsBlank';E={$_.EncryptionTypesAsString -like \"*RC4*\"}} | `\nWhere{-not $_.HasRC4OrIsBlank} \n \n \n \n \n Phew, a page into this article and now we’re ready to get started. The problematic patch caused problems if it was installed on domain controllers in environments with recommended improvements to Kerberos encryption. There are 3 main types of encryption that Kerberos can currently be configured to use: DES, RC4, and AES. DES is easily brute forced and hasn’t been considered secure since the 90s, RC4 is more common, and AES is currently the most secure of the three options. Objects that did not allow RC4 for Kerberos authentication stopped working after the patch. Security conscious folks that only allowed AES ran into problems with things like ADFS, gMSAs, RDP, accessing file shares, and even printing. My clients wanted to be up to date with the latest patches, but also didn’t want to break their environments so this is a quick investigation of if their environments would break. \n To determine if AD objects in your environment will be impacted by applying the November 8 th 2022 rollup you need to parse information about the msDS-SupportedEncryptionTypes property of AD objects that could be impacted and analyze them. The msDS-SupportedEncryptionTypes property defines which encryption types are supported, however it is not easy to read since it is encoded. I know when someone says msDS-SupportedEncryptionTypes of 8 I immediately think of AES 128, but to make it easy, let’s use a PowerShell function. \n \n There is a great article on understanding encryption types here: https://techcommunity.microsoft.com/t5/core-infrastructure-and-security/decrypting-the-selection-of-supported-kerberos-encryption-types/ba-p/1628797 \n \n The main takeaway I got from the article was the following table: \n \n \n \n \n Decimal Value \n \n \n Hex Value \n \n \n Supported Encryption Types \n \n \n \n \n 0 \n \n \n 0x0 \n \n \n Not defined - defaults to RC4_HMAC_MD5 \n \n \n \n \n 1 \n \n \n 0x1 \n \n \n DES_CBC_CRC \n \n \n \n \n 2 \n \n \n 0x2 \n \n \n DES_CBC_MD5 \n \n \n \n \n 3 \n \n \n 0x3 \n \n \n DES_CBC_CRC, DES_CBC_MD5 \n \n \n \n \n 4 \n \n \n 0x4 \n \n \n RC4 \n \n \n \n \n 5 \n \n \n 0x5 \n \n \n DES_CBC_CRC, RC4 \n \n \n \n \n 6 \n \n \n 0x6 \n \n \n DES_CBC_MD5, RC4 \n \n \n \n \n 7 \n \n \n 0x7 \n \n \n DES_CBC_CRC, DES_CBC_MD5, RC4 \n \n \n \n \n 8 \n \n \n 0x8 \n \n \n AES 128 \n \n \n \n \n 9 \n \n \n 0x9 \n \n \n DES_CBC_CRC, AES 128 \n \n \n \n \n 10 \n \n \n 0xA \n \n \n DES_CBC_MD5, AES 128 \n \n \n \n \n 11 \n \n \n 0xB \n \n \n DES_CBC_CRC, DES_CBC_MD5, AES 128 \n \n \n \n \n 12 \n \n \n 0xC \n \n \n RC4, AES 128 \n \n \n \n \n 13 \n \n \n 0xD \n \n \n DES_CBC_CRC, RC4, AES 128 \n \n \n \n \n 14 \n \n \n 0xE \n \n \n DES_CBC_MD5, RC4, AES 128 \n \n \n \n \n 15 \n \n \n 0xF \n \n \n DES_CBC_CBC, DES_CBC_MD5, RC4, AES 128 \n \n \n \n \n 16 \n \n \n 0x10 \n \n \n AES 256 \n \n \n \n \n 17 \n \n \n 0x11 \n \n \n DES_CBC_CRC, AES 256 \n \n \n \n \n 18 \n \n \n 0x12 \n \n \n DES_CBC_MD5, AES 256 \n \n \n \n \n 19 \n \n \n 0x13 \n \n \n DES_CBC_CRC, DES_CBC_MD5, AES 256 \n \n \n \n \n 20 \n \n \n 0x14 \n \n \n RC4, AES 256 \n \n \n \n \n 21 \n \n \n 0x15 \n \n \n DES_CBC_CRC, RC4, AES 256 \n \n \n \n \n 22 \n \n \n 0x16 \n \n \n DES_CBC_MD5, RC4, AES 256 \n \n \n \n \n 23 \n \n \n 0x17 \n \n \n DES_CBC_CRC, DES_CBC_MD5, RC4, AES 256 \n \n \n \n \n 24 \n \n \n 0x18 \n \n \n AES 128, AES 256 \n \n \n \n \n 25 \n \n \n 0x19 \n \n \n DES_CBC_CRC, AES 128, AES 256 \n \n \n \n \n 26 \n \n \n 0x1A \n \n \n DES_CBC_MD5, AES 128, AES 256 \n \n \n \n \n 27 \n \n \n 0x1B \n \n \n DES_CBC_MD5, DES_CBC_MD5, AES 128, AES 256 \n \n \n \n \n 28 \n \n \n 0x1C \n \n \n RC4, AES 128, AES 256 \n \n \n \n \n 29 \n \n \n 0x1D \n \n \n DES_CBC_CRC, RC4, AES 128, AES 256 \n \n \n \n \n 30 \n \n \n 0x1E \n \n \n DES_CBC_MD5, RC4, AES 128, AES 256 \n \n \n \n \n 31 \n \n \n 0x1F \n \n \n DES+A1:C33_CBC_MD5, DES_CBC_MD5, RC4, AES 128, AES 256 \n \n \n \n \n \n As a human, when I’m viewing my AD objects, I would much rather see the right column than the left column of the table above. If you consider the msDS-SupportedEncryptionNumber as binary the following table is a little easier to read. \n \n \n \n \n msDS-SupportedEncryptionType \n \n \n Definition \n \n \n \n \n 1 \n \n \n DES_DBC_CRC \n \n \n \n \n 2 \n \n \n DES_CBC_MD5 \n \n \n \n \n 4 \n \n \n RC4 \n \n \n \n \n 8 \n \n \n AES 128 \n \n \n \n \n 16 \n \n \n AES 256 \n \n \n \n \n \n As an example, an object has a msDS-SupportedEncryptionNumber of 13 defined. 13 in binary is 01101. 01101 has a 1 in the 1, 4, and 8 positions to add up to 13 so DES_DBC_CRC, RC4, and AES 128 are supported encryption types. The following function does the same process. \n \n \n \n <#\n.Synopsis\n Turns the integer stored in msDS-SupportedEncryptionTypes into a human readable value\n.DESCRIPTION\n Turns the integer stored in msDS-SupportedEncryptionTypes into a human readable value\n For more info on the encryption types: https://techcommunity.microsoft.com/t5/core-infrastructure-and-security/decrypting-the-selection-of-supported-kerberos-encryption-types/ba-p/1628797\n.EXAMPLE\n Get-ETypeDefiniton 7\n.PARAMETER msDSSupportedEncryptionTypes\n Returns an array of results indicating the supported encryption types\n.PARAMETER AsString\n Returns the result as a comma delimited string\n#>\nfunction Get-ETypeDefinition\n{\n [CmdletBinding()]\n Param\n (\n [Parameter(Mandatory=$true,\n ValueFromPipelineByPropertyName=$true,\n Position=0)]\n $msDSSupportedEncryptionTypes,\n [switch] $AsString\n )\n Begin\n {\n $ETypes = [HASHTABLE]@{\n 0 = 'Not defined - defaults to RC4_HMAC_MD5'\n 1 = 'DES_CBC_CRC'\n 2 = 'DES_CBC_MD5'\n 4 = 'RC4'\n 8 = 'AES 128'\n 16 = 'AES 256'\n }\n }\n Process\n {\n $Types = $ETypes.keys | %{\n If([int]($msDSSupportedEncryptionTypes -band [int]$_) -ne 0){\n $ETypes[[int]$_]\n }\n }\n If($AsString){\n $Types -join(',')\n }Else{\n $Types\n }\n }\n End\n {\n }\n} \n \n \n \n In the function above I made a hash table then compared the hash table to the msDS-SupportedEncryptionTypes. Some folks may not be familiar with -band. Band is a bitwise operator that returns bitwise and, so I know when both the number in my hash table and the number being tested are the same for a given binary value. \n Example output: \n \n \n \n PS C:\\ [19]> Get-ETypeDefinition 13\nAES 128\nRC4\nDES_CBC_CRC\nPS C:\\ [6]> Get-ETypeDefinition 13 -AsString\nAES 128,RC4,DES_CBC_CRC\nPS C:\\ [18]> \n \n \n \n Now that we have an easy way to decode our msDS-SupportedEncryptionTypes want to know which objects have which encryption types. We want to inspect user objects, computer objects, and gMSA objects. I’ll work through computer objects as an example, then provide code for all of them. \n Get-ADComputer is an old trusty cmdlet so let’s just get all computers including their encryption types and just get a handle on what we have. \n \n \n \n $computers = Get-ADComputer -Filter * -Properties msDS-SupportedEncryptionTypes\n$computers | Group-Object msDS-SupportedEncryptionTypes | select count,name \n \n \n \n George ran it in Contoso’s resources domain and got the following output. \n \n \n \n PS C:\\> $computers = Get-ADComputer -Filter * -Properties msDS-SupportedEncryptionTypes\nPS C:\\> $computers | Group-Object msDS-SupportedEncryptionTypes | select count,name\nCount Name\n----- ----\n 20 28 \n 1 \n 1 30 \n 1 31 \n 1 8 \n \n \n \n That is interesting but means nothing to us humans. Now we can add in the Get-ETypeDefinition function to give readable output. By using named expressions, we can get some useful output. \n \n \n \n $computers | `\ngroup msDS-SupportedEncryptionTypes | `\nselect count,name,'msDS-SupportedEncryptionTypes', @{N='EncryptionTypes';E={Get-ETypeDefinition -msDSSupportedEncryptionTypes ($_.Name)}}, @{N='EncryptionTypesAsString';E={Get-ETypeDefinition -msDSSupportedEncryptionTypes ($_.Name) -AsString}} | `\nselect count,name,EncryptionTypes,@{N='HasRC4OrIsBlank';E={$_.EncryptionTypesAsString -like \"*RC4*\"}} \n \n \n \n George ran this can got more useful output below: \n \n \n \n PS C:\\> $computers | `\ngroup msDS-SupportedEncryptionTypes | `\nselect count,name,'msDS-SupportedEncryptionTypes', @{N='EncryptionTypes';E={Get-ETypeDefinition -msDSSupportedEncryptionTypes ($_.Name)}}, @{N='EncryptionTypesAsString';E={Get-ETypeDefinition -msDSSupportedEncryptionTypes ($_.Name) -AsString}} | `\nselect count,name,EncryptionTypes,@{N='HasRC4OrIsBlank';E={$_.EncryptionTypesAsString -like \"*RC4*\"}}\n\nCount Name EncryptionTypes HasRC4OrIsBlank\n----- ---- --------------- ---------------\n 20 28 {AES 128, AES 256, RC4} True\n 1 Not defined - defaults to RC4_HMAC_MD5 True\n 1 30 {AES 128, AES 256, RC4, DES_CBC_MD5} True\n 1 31 {AES 128, AES 256, RC4, DES_CBC_MD5...} True\n 2 8 AES 128 False \n \n \n \n Now George knows that there are computers that will have a problem if the November 8 th patches are applied. George wants to know which computers will be impacted so we generate a list using the query below. \n \n \n \n $computers | `\nselect name,'msDS-SupportedEncryptionTypes', @{N='EncryptionTypes';E={Get-ETypeDefinition -msDSSupportedEncryptionTypes ($_.'msDS-SupportedEncryptionTypes')}}, @{N='EncryptionTypesAsString';E={Get-ETypeDefinition -msDSSupportedEncryptionTypes ($_.'msDS-SupportedEncryptionTypes') -AsString}} | `\nselect name,EncryptionTypes,@{N='HasRC4OrIsBlank';E={$_.EncryptionTypesAsString -like \"*RC4*\"}} | `\nWhere{-not $_.HasRC4OrIsBlank} \n \n \n \n When George ran that query, he got: \n \n \n \n PS C:\\> $computers | `\nselect name,'msDS-SupportedEncryptionTypes', @{N='EncryptionTypes';E={Get-ETypeDefinition -msDSSupportedEncryptionTypes ($_.'msDS-SupportedEncryptionTypes')}}, @{N='EncryptionTypesAsString';E={Get-ETypeDefinition -msDSSupportedEncryptionTypes ($_.'msDS-SupportedEncryptionTypes') -AsString}} | `\nselect name,EncryptionTypes,@{N='HasRC4OrIsBlank';E={$_.EncryptionTypesAsString -like \"*RC4*\"}} | `\nWhere{-not $_.HasRC4OrIsBlank}\n\nname EncryptionTypes HasRC4OrIsBlank\n---- --------------- ---------------\ntest6 AES 128 False\nVeryImportantComputer AES 128 False \n \n \n \n Now George knows that computers with the name ‘test6’ and ‘VeryImportantComputer’ will have problems if the November 8 th patches are applied to DCs without performing the proper workaround. \n There was a workaround that wasn’t officially published when clients first ran into this issue however it was available by opening a CSS case or contacting your Microsoft account manager. Now that it has been a few days the out of band patches are available at the top of this article. \n Just like George and I did analysis on computers you can leverage the same Get-ETypeDefinition function above to help you analyze all objects, user objects or gMSAs. Be sure to define the ‘Get-ETypeDefinition’ function in the host you’re using before running these queries. All I’m doing is getting gMSA or user objects, then passing the same objects over the pipeline to be filtered and displayed. \n \n Any AD object: \n \n \n \n Get-ADObject -Filter * -Properties msDS-SupportedEncryptionTypes | `\nselect name,objectClass,'msDS-SupportedEncryptionTypes', @{N='EncryptionTypes';E={Get-ETypeDefinition -msDSSupportedEncryptionTypes ($_.'msDS-SupportedEncryptionTypes')}}, @{N='EncryptionTypesAsString';E={Get-ETypeDefinition -msDSSupportedEncryptionTypes ($_.'msDS-SupportedEncryptionTypes') -AsString}} | `\nselect name,objectClass,EncryptionTypes,@{N='HasRC4OrIsBlank';E={$_.EncryptionTypesAsString -like \"*RC4*\"}} | `\nWhere{-not $_.HasRC4OrIsBlank} \n \n \n \n Computers: \n \n \n \n Get-ADComputer -Filter * -Properties msDS-SupportedEncryptionTypes | `\nselect name,'msDS-SupportedEncryptionTypes', @{N='EncryptionTypes';E={Get-ETypeDefinition -msDSSupportedEncryptionTypes ($_.'msDS-SupportedEncryptionTypes')}}, @{N='EncryptionTypesAsString';E={Get-ETypeDefinition -msDSSupportedEncryptionTypes ($_.'msDS-SupportedEncryptionTypes') -AsString}} | `\nselect name,EncryptionTypes,@{N='HasRC4OrIsBlank';E={$_.EncryptionTypesAsString -like \"*RC4*\"}} | `\nWhere{-not $_.HasRC4OrIsBlank} \n \n \n \n gMSAs: \n \n \n \n Get-ADServiceAccount -Filter * -Properties msDS-SupportedEncryptionTypes | `\nselect name,'msDS-SupportedEncryptionTypes', @{N='EncryptionTypes';E={Get-ETypeDefinition -msDSSupportedEncryptionTypes ($_.'msDS-SupportedEncryptionTypes')}}, @{N='EncryptionTypesAsString';E={Get-ETypeDefinition -msDSSupportedEncryptionTypes ($_.'msDS-SupportedEncryptionTypes') -AsString}} | `\nselect name,EncryptionTypes,@{N='HasRC4OrIsBlank';E={$_.EncryptionTypesAsString -like \"*RC4*\"}} | `\nWhere{-not $_.HasRC4OrIsBlank} \n \n \n \n Users: \n \n \n \n Get-ADUser -Filter * -Properties msDS-SupportedEncryptionTypes | `\nselect name,'msDS-SupportedEncryptionTypes', @{N='EncryptionTypes';E={Get-ETypeDefinition -msDSSupportedEncryptionTypes ($_.'msDS-SupportedEncryptionTypes')}}, @{N='EncryptionTypesAsString';E={Get-ETypeDefinition -msDSSupportedEncryptionTypes ($_.'msDS-SupportedEncryptionTypes') -AsString}} | `\nselect name,EncryptionTypes,@{N='HasRC4OrIsBlank';E={$_.EncryptionTypesAsString -like \"*RC4*\"}} | `\nWhere{-not $_.HasRC4OrIsBlank} \n \n \n \n \n A few PowerShell queries made it quick to verify that some of my clients are impacted by the November 8 th patches, so they need to perform a workaround or not patch their DCs until the out-of-band patch is released. \n \n Have fun scripting! \n \n References: \n Decoding msDS-SupportedEncryptionTypes - https://techcommunity.microsoft.com/t5/core-infrastructure-and-security/decrypting-the-selection-of-supported-kerberos-encryption-types/ba-p/1628797 \n Interpreting the Supported Encryption Types - https://learn.microsoft.com/en-us/archive/blogs/petergu/interpreting-the-supportedencryptiontypes-registry-key \n Configure encryption types allowed for Kerberos: https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-R2-and-2012/jj852180(v=ws.11) \n Kerberos protocol registry entries and KDC configuration keys in Windows: https://learn.microsoft.com/en-us/troubleshoot/windows-server/windows-security/kerberos-protocol-registry-kdc-configuration-keys ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"18808","kudosSumWeight":8,"repliesCount":1,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDE","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjc5ODY5LTQxOTkyNWkxMEUzNEVDMkNCNUU3NjUx?revision=9\"}"}}],"totalCount":1,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"coverImage":null,"coverImageProperties":{"__typename":"CoverImageProperties","style":"STANDARD","titlePosition":"BOTTOM","altText":""}},"Conversation:conversation:3598286":{"__typename":"Conversation","id":"conversation:3598286","topic":{"__typename":"BlogTopicMessage","uid":3598286},"lastPostingActivityTime":"2022-08-25T02:00:00.022-07:00","solved":false},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNTk4Mjg2LTM5NTMzNWk5RkRBNDNERTJDQThCNzZE?revision=2\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNTk4Mjg2LTM5NTMzNWk5RkRBNDNERTJDQThCNzZE?revision=2","title":"Pic1.png","associationType":"BODY","width":1248,"height":552,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNTk4Mjg2LTM5NTMzN2kxRTA0MkM4M0YwQzM5NUY3?revision=2\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNTk4Mjg2LTM5NTMzN2kxRTA0MkM4M0YwQzM5NUY3?revision=2","title":"Picture2.png","associationType":"BODY","width":1248,"height":39,"altText":null},"BlogTopicMessage:message:3598286":{"__typename":"BlogTopicMessage","subject":"Q: Who is adding a bunch of DNS records to my environment?","conversation":{"__ref":"Conversation:conversation:3598286"},"id":"message:3598286","revisionNum":2,"uid":3598286,"depth":0,"board":{"__ref":"Blog:board:CoreInfrastructureandSecurityBlog"},"author":{"__ref":"User:user:399999"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":" A: Everyone wants to go back in time to enable auditing before an incident has happened, but in this case, we can do some queries to figure it out without special auditing enabled. ","introduction":"","metrics":{"__typename":"MessageMetrics","views":6219},"postTime":"2022-08-25T02:00:00.022-07:00","lastPublishTime":"2022-08-25T02:00:00.022-07:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" The other day a client asked everyone in operations who added some odd DNS records, everyone on the admin team denied making any changes, no one in engineering did it either. They determined the user that made the new record but then got curious, what if folks had added many other records but no one had noticed? \n I decided to generate a list of who had created DNS records to cross-reference with the list of folks we expected. \n Auditing is like backups, enabling it is a higher priority after a big mistake. Fortunately, with DNS we can figure out a few neat things without digging through auditing logs. \n \n When a user creates a DNS record that user is made the owner of that record as we can see here by looking through dnsmgmt.msc at a record George created in the resources.contoso.com zone. \n \n \n Of course, we can do the same thing through PowerShell: \n \n (Get-Acl 'AD:\\DC=MyFavoriteDNSRecord,DC=resources.contoso.com,CN=MicrosoftDNS,DC=DomainDnsZones,DC=resources,DC=contoso,DC=com').Owner \n \n \n \n \n \n \n \n Disclaimer \n The sample scripts are not supported under any Microsoft standard support program or service. The sample scripts are provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages. \n \n \n \n \n \n Now that I have a one-liner to determine the owner of a single record, I want to summarize the creator of every record in the environment to see if there are folks creating records that we don’t know about. To do this we need to get every zone, then every record in every zone, then get the owner. \n \n $ComputerName = 'resources.contoso.com'\n $Zones = Get-DnsServerZone -ComputerName $ComputerName | Where-Object { $_.IsDsintegrated } #get all zones I care about\n $DNSRecords = $Zones | Get-DnsServerResourceRecord -ComputerName $ComputerName #get every DNS record\n \n $RecordAndOwner = $DNSRecords | ForEach-Object {\n [pscustomobject]@{\n Record = $_\n Owner = (Get-Acl $('AD:\\' + $_.DistinguishedName)).Owner\n }\n } \n \n \n \n Great, now I have a bunch of useful information, but if we just look at it without any special effort it is too ugly to do anything useful with. Here is the beginning of what I got in my lab: \n \n PS C:\\> $RecordAndOwner\n\nRecord Owner \n------ ----- \nDnsServerResourceRecord NT AUTHORITY\\SYSTEM \nDnsServerResourceRecord NT AUTHORITY\\SYSTEM \nDnsServerResourceRecord NT AUTHORITY\\SYSTEM \nDnsServerResourceRecord NT AUTHORITY\\SYSTEM \nDnsServerResourceRecord NT AUTHORITY\\SYSTEM \nDnsServerResourceRecord NT AUTHORITY\\SYSTEM \nDnsServerResourceRecord RESOURCES\\RESOURCESDC2$ \nDnsServerResourceRecord NT AUTHORITY\\SYSTEM \nDnsServerResourceRecord NT AUTHORITY\\SYSTEM \nDnsServerResourceRecord NT AUTHORITY\\SYSTEM \nDnsServerResourceRecord NT AUTHORITY\\SYSTEM \nDnsServerResourceRecord NT AUTHORITY\\SYSTEM \nDnsServerResourceRecord NT AUTHORITY\\SYSTEM \nDnsServerResourceRecord NT AUTHORITY\\SYSTEM \nDnsServerResourceRecord NT AUTHORITY\\SYSTEM \nDnsServerResourceRecord NT AUTHORITY\\SYSTEM \n \n \n \n …Then there were way more records, but this doesn’t tell us much, so we need a better way of reviewing it. \n \n Here is a more useful summary: \n \n $RecordAndOwner | Group-Object owner | Select-Object count, name | Sort-Object name\nCount Name \n----- ---- \n 61 NT AUTHORITY\\SYSTEM \n 1 RESOURCES\\ATA1$ \n 4 RESOURCES\\BillG \n 1 RESOURCES\\DEMOSERVER$ \n 1 RESOURCES\\EARS$ \n 2 RESOURCES\\george \n 1 RESOURCES\\NEW2019$ \n 1 RESOURCES\\OLD2012R2$ \n 1 RESOURCES\\OLD2016$ \n 1 RESOURCES\\RESOURCESCA$ \n 2 RESOURCES\\RESOURCESDC2$ \n 1 RESOURCES\\RESOURCESWORKST$ \n \n \n \n Unfortunately, this still shows all the computers showing the records that they registered and I don’t really care about those. \n Here I narrow it down to more useful insights by removing the records created by computers. \n \n $RecordAndOwner | Group-Object owner | Where-Object { $_.Name -notlike '*$' } | Select-Object count, name | Sort-Object name\n\nCount Name \n----- ---- \n 61 NT AUTHORITY\\SYSTEM\n 4 RESOURCES\\BillG \n 2 RESOURCES\\george \n \n \n \n Now I have a list of every user account that is an owner of a DNS record and how many they are the owner of. Wait a second… who is this BillG guy making changes? Let’s investigate what he has been doing. \n \n ($RecordAndOwner | Where-Object { $_.owner -eq 'resources\\billg' }).Record\n\nHostName RecordType Type Timestamp TimeToLive RecordData \n-------- ---------- ---- --------- ---------- ---------- \nasdf2 A 1 0 01:00:00 3.3.3.3 \nasdf2 A 1 0 01:00:00 2.2.2.2 \nasdf2 A 1 0 01:00:00 1.1.1.1 \nasdf3 CNAME 5 0 01:00:00 asdf2.resources.contoso.com . \n \n \n \n It looks like BillG is creating records that aren’t very useful. Based on this I can go talk to BillG to determine what he is up to, maybe he forgot that he was in production when he was testing. \n \n Here is everything we did: \n \n $ComputerName = 'resources.contoso.com'\n$Zones = Get-DnsServerZone -ComputerName $ComputerName | Where-Object { $_.IsDsintegrated } #get all zones I care about\n$DNSRecords = $Zones | Get-DnsServerResourceRecord -ComputerName $ComputerName #get every DNS record\n \n$RecordAndOwner = $DNSRecords | ForEach-Object {\n [pscustomobject]@{\n Record = $_\n Owner = (Get-Acl $('AD:\\' + $_.DistinguishedName)).Owner\n }\n}\n \n$RecordAndOwner #List all the owners... wait, that is too much stuff and too hard to read\n \n#List everyone that has created a DNS record and how many records they have created (only checks owner, but owner is the creator by default)\n$RecordAndOwner | Group-Object owner | Select-Object count, name | Sort-Object name\n \n#Omit records created by servers\n$RecordAndOwner | Group-Object owner | Where-Object { $_.Name -notlike '*$' } | Select-Object count, name | Sort-Object name\n \n#Investigate which records BillG has created \n($RecordAndOwner | Where-Object { $_.owner -eq 'resources\\billg' }).Record \n \n \n \n Once again, a difficult manual task became nearly trivial with a few lines of PowerShell. We reviewed tens of thousands of DNS records in just a few minutes. \n In this case we got away without the need for auditing, however configuring proper DNS auditing before you need it is very important. Properly configuring DNS auditing is outside the scope of this article, so I’ve referenced valuable articles from a colleague. \n \n Have fun scripting! \n \n \n Additional reading: \n \n Who Moved the DNS Cheese? Auditing for AD-Integrated DNS Zone and Record Deletions - Microsoft Tech Community \n How to Save the DNS Cheese. Protect AD-Integrated DNS Zones from Accidental Deletions - Microsoft Tech Community \n ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"8456","kudosSumWeight":4,"repliesCount":0,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDE","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNTk4Mjg2LTM5NTMzNWk5RkRBNDNERTJDQThCNzZE?revision=2\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDI","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNTk4Mjg2LTM5NTMzN2kxRTA0MkM4M0YwQzM5NUY3?revision=2\"}"}}],"totalCount":2,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"coverImage":null,"coverImageProperties":{"__typename":"CoverImageProperties","style":"STANDARD","titlePosition":"BOTTOM","altText":""}},"Conversation:conversation:3201822":{"__typename":"Conversation","id":"conversation:3201822","topic":{"__typename":"BlogTopicMessage","uid":3201822},"lastPostingActivityTime":"2022-03-23T15:38:01.732-07:00","solved":false},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMjAxODIyLTM1NzI4MWlBQjFBMUVGMDFFNjVDNERD?revision=20\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMjAxODIyLTM1NzI4MWlBQjFBMUVGMDFFNjVDNERD?revision=20","title":"HomoglyphTitlePic.PNG","associationType":"TEASER","width":218,"height":209,"altText":null},"BlogTopicMessage:message:3201822":{"__typename":"BlogTopicMessage","subject":"When Is True Not Equal To True?","conversation":{"__ref":"Conversation:conversation:3201822"},"id":"message:3201822","revisionNum":20,"uid":3201822,"depth":0,"board":{"__ref":"Blog:board:CoreInfrastructureandSecurityBlog"},"author":{"__ref":"User:user:399999"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":" \n An investigation of homoglyphs, their impact on code, and how to detect them. ","introduction":"","metrics":{"__typename":"MessageMetrics","views":6119},"postTime":"2022-03-21T06:51:11.512-07:00","lastPublishTime":"2022-03-22T12:49:29.782-07:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" \n When is true not equal to true? \n An investigation of homoglyphs, their impact on code, and how to detect them. \n \n Statement of the problem \n Here is something I did for fun but stuff like this would be very difficult to debug if it made it into my code. It looks like the values of $true and $false can be changed at will below. \n \n PS C:\\> $true -eq $true\nTrue\n\nPS C:\\> $true -eq $truе\nFalse\n\nPS C:\\> $false -eq $false\nTrue\n\nPS C:\\> $fаlѕе -eq $false\nFalse \n \n \n \n Summary \n This article will walk through homoglyphs and a proposed type of attack that I have not yet seen in the wild, but I presume has occurred. Every programming language I’m aware of is impacted but I don’t know every programming language, so I’ll stick to PowerShell for the proofs of concepts below. I’ll also show code that I wrote to detect this vulnerability in PowerShell code which can be built upon to create scanners for other languages. The problems I present here can be detected if proper unit testing is in place. I don’t like writing unit tests either, but this is me Pestering you to consider adding unit testing to your pipeline. \n Homoglyphs are two or more characters that have similar or identical shapes but are stored by the computer as different characters. Homoglyphs are nothing new, people have been familiar with them and used them for good and evil since before computers like on some old typewriters that didn’t have a “1” key since there was already a lowercase “L”. \n \n Disclaimer: The sample scripts are not supported under any Microsoft standard support program or service. The sample scripts are provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages. \n \n Disclaimer: Microsoft does not endorse any third-party products or services. The third-party products or services are not supported under any Microsoft standard support program or service. The third-party products or services are available AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the third-party products or services and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the third-party products or services be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages. \n \n If you’re not familiar with Trojan Source it is an interesting fun read available at https://trojansource.codes/ or view the original whitepaper at https://trojansource.codes/trojan-source.pdf The Trojan Source whitepaper makes a mention of homoglyphs however I investigate a little more here. \n Leet is an example of homoglyph use: 1337 5p34k 15 4150 4 7yp3 0f h0m0g1yph \n Microsoft quickly responded to the Trojan Source publication and quickly put in place notifications to let users know if a GitHub repository or VS Code being modified contained bidirectional (bidi) Unicode characters. Homoglyphs were also mentioned in the Trojan Source paper, but I was unable to find a tool to scan my repositories for homoglyphs so I wrote one. The module can be installed by running Install-Module HomoglyphDetection or by going to the GitHub repository https://github.com/PaulHCode/HomoglyphDetection. \n Open-source projects with modern tools like GitHub make it easy for there to be hundreds of developers all contribute to the same project which is great for development speed and agility but presents problems with knowing the entire code base is secure. No single developer owns every variable and function and by just tweaking one character one place major problems can be introduced and it can be very difficult to detect. \n There are many characters that look identical but are stored as different characters electronically, some examples shown below. \n \n PS C:\\> [int][char]'i'\n105\n\nPS C:\\> [int][char]'і'\n1110\n\nPS C:\\> [int][char]'a'\n97\n\nPS C:\\> [int][char]'а'\n1072\n\nPS C:\\> \n \n \n \n Here you can see how someone could make two identical looking variables with different values. I have enough trouble debugging code when I can tell the difference between my variables but if someone introduced identical looking variables in a large project, I might never find the problem. \n \n PS C:\\> $i = $true\n\nPS C:\\> $і = $false\n\nPS C:\\> $i\nTrue\n\nPS C:\\> $і\nFalse\n\nPS C:\\> $i -eq $і\nFalse\n \n \n \n Function names could also have identical looking names. Projects have many functions loaded from many files and functions and variables used in one place could be loaded from many other places. Below are four different functions that have indistinguishable names. The top function is the original function that developers intended to be in the project. A different function that looks identical could be contributed to the project then different versions of the function can be called in different parts of the project which would yield anomalous behavior. \n \n Function Foo{\"Hello world\"}\nFunction Fοο{\"Goodbye world\"}\nFunction Ϝoo{\"Weird world\"}\nFunction Foo‚{\"Invisible world\"}\nFoo;Fοο;Ϝoo;Foo‚\nHello world\nGoodbye world\nWeird world\nInvisible world \n \n \n \n In a larger script or program, there could be something like the snippet below. \n \n If(!$Prevented){\n #grant access and do things not everyone should be allowed to do here\n} \n \n \n If one of the characters in “Prevented” was changed to a homoglyph, then $Prevented would be an undefined variable which evaluates to $Null, and in an if statement $Null evaluates to $False and Not $Null evaluates to $True. \n \n Problem detection \n It is easy to generate homoglyphs and can easily be done with http://homoglyphs.net/. It is harder to detect if one word is a homoglyph of another though since each character could be any number of different characters. Even if each character only had 3 other characters that looked like it, the number of combinations possible for an N-character word is 4 N -1. A 5-character variable therefore could be represented by 1023 different combinations of characters, and that doesn’t even include options like invisible characters. \n \n PS C:\\> $truе -eq $true\nFalse \n \n \n In the example above, we don’t see the reflexive property of equality breaking down, but it is impossible to tell the difference between the two values that both look like $true. The one on the right is the expected automatic variable, however the one on the left uses character 1077 for ‘e’ instead of character 101. An undefined variable is not going to be equal to $true or $false, so by modifying a single character in a PowerShell script the code can dramatically change in function while appearing identical in the text editor and PowerShell host. \n \n PS C:\\> (\"true\").ToCharArray() | %{\"$_ - $([int][char]$_)\"}\nt - 116\nr - 114\nu - 117\ne - 101\n\nPS C:\\> (\"truе\").ToCharArray() | %{\"$_ - $([int][char]$_)\"}\nt - 116\nr - 114\nu - 117\nе - 1077\n\nPS C:\\> \n \n \n \n My first thought was that use of characters with a high numerical value were probably not used in production code; after all, I only use the characters I can see on my keyboard which top out at around 126. If I discovered high value characters in code, then maybe it is suspicious. \n I checked which characters are used in common PowerShell by simply scanning all the PowerShell scripts on my computer. My computer isn’t a great reflection of what is used by everyone, but at least it was a good start. I did the quick check using the following: \n \n $bigArray = @()\n$count = 0\n$files = (Get-ChildItem '<my scripts location>' -include '*.ps1' -recurse)\n$max = $files.count\nForEach ($file in $files) {\n Write-Progress -Status \"checking file $count of $max\" -Activity \"$($file.fullname)\" -PercentComplete (100 * ($count / $max))\n $bigArray += (Get-Content $file).tochararray() | ForEach-Object { [int]$_ }\n $count++\n}\n$analysis = $bigArray | Group-Object\n$analysis | Select-Object count, @{N = 'Name2'; E = { [int]$_.Name } }, @{N = 'char'; E = { [char][int]($_.name) } } | Sort-Object Name2 \n \n \n To my surprise, high numbered characters were being used; not a ton, but I couldn’t just dismiss them. I’m from the United States and only work with the English language, but there are probably developers using many other Unicode characters that are higher numbered in other languages, so I needed a better way to detect unusual characters rather than just alerting on high numbered characters. \n \n Automating detection \n I devised a plan to detect homoglyphs in my code: \n \n Pull every variable and function name out of the code to be examined. \n Convert each character of the names to the more common character I know that looks like it. \n Compare all the converted values to each other to see if any of the converted values match while the actual values are different. \n \n If any of the items meet those criteria, then they should be examined by a human for validation. \n \n Get every variable and function name \n Getting every variable and function can be achieved easily in PowerShell using abstract syntax trees. Since there are other languages out there, my module allows you to specify custom parsing using regular expressions and is easily extensible for you to add in your own parser for other file types. The parsing for PowerShell I used was simple but effective, as seen below. \n \n $AST = [System.Management.Automation.Language.Parser]::ParseFile(\n $file,\n [ref]$null,\n [ref]$Null\n ) \n$AST.FindAll({$args[0] -is [System.Management.Automation.Language.FunctionDefinitionAst]}, $true) \n$AST.FindAll({$args[0] -is [System.Management.Automation.Language.VariableExpressionAst]}, $true) \n \n \n Convert each character to a Latin character that looks the same \n I decided to compare variables and function names so I would need to make a mapping of every character and which Latin character it looks like. Unfortunately, there are 65535 characters in Unicode and I’m lazy, so I don’t want to look at all of them and analyze each one and which others it looks like. I found a function someone else wrote and slightly modified it to create a picture of each character, then wrote a simple function to have OCR give me what character the picture looks like; this automated the process of building a lookup table. \n \n function Convert-TextToImage\n{\n# code from: https://community.idera.com/database-tools/powershell/powertips/b/tips/posts/converting-text-to-image\n param\n (\n [String]\n [Parameter(Mandatory)]\n $Text,\n \n [String]\n $Font = 'Microsoft Sans Serif', #'Times New Roman', #'Consolas',\n \n [ValidateRange(5,400)]\n [Int]\n $FontSize = 24,\n\n [string]\n $filename=\"$env:temp\\$(Get-Random).png\"\n )\n #I slightly modified this function from: https://community.idera.com/database-tools/powershell/powertips/b/tips/posts/converting-text-to-image\n\n [System.Windows.Media.Brush]$Foreground = [System.Windows.Media.Brushes]::Black\n [System.Windows.Media.Brush]$Background = [System.Windows.Media.Brushes]::White\n\n \n If($Text.Length -gt 1){\n $psm = 13\n $font = 'Consolas' #'Mitra'#'Microsoft Sans Serif'\n $fontSize = 50\n}Else{\n $psm = 10\n $font = 'Times New Roman'\n $fontSize = 20\n}\n\n # take a simple XAML template with some text \n $xaml = @\"\n<TextBlock\n xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">$Text</TextBlock>\n\"@\n\n Add-Type -AssemblyName PresentationFramework\n \n # turn it into a UIElement\n $reader = [XML.XMLReader]::Create([IO.StringReader]$XAML)\n $result = [Windows.Markup.XAMLReader]::Load($reader)\n \n # refine its properties\n $result.FontFamily = $Font\n $result.FontSize = $FontSize\n $result.Foreground = $Foreground\n $result.Background = $Background\n \n # render it in memory to the desired size\n $result.Measure([System.Windows.Size]::new([Double]::PositiveInfinity, [Double]::PositiveInfinity))\n $result.Arrange([System.Windows.Rect]::new($result.DesiredSize))\n $result.UpdateLayout()\n \n # write it to a bitmap and save it as PNG\n $render = [System.Windows.Media.Imaging.RenderTargetBitmap]::new($result.ActualWidth, $result.ActualHeight, 96, 96, [System.Windows.Media.PixelFormats]::Default)\n $render.Render($result)\n Start-Sleep -Seconds 1\n $encoder = [System.Windows.Media.Imaging.PngBitmapEncoder]::new()\n $encoder.Frames.Add([System.Windows.Media.Imaging.BitmapFrame]::Create($render))\n $filestream = [System.IO.FileStream]::new($filename, [System.IO.FileMode]::Create)\n $encoder.Save($filestream)\n \n # clean up\n $reader.Close() \n $reader.Dispose()\n \n $filestream.Close()\n $filestream.Dispose()\n \n}\n \n\nfunction Get-OCRByChar\n{\n [CmdletBinding()]\n Param\n (\n [Parameter(Mandatory=$true,\n ValueFromPipelineByPropertyName=$true,\n Position=0,\n ParameterSetName='Parameter Set text')]\n $Text,\n [Parameter(Mandatory=$true,\n ValueFromPipelineByPropertyName=$true,\n Position=0,\n ParameterSetName='Parameter Set char')]\n $Char\n )\n\n Begin\n {\n If($Char){\n $Text = [string]$Char\n }\n }\n Process\n {\n $count = 0\n $word = ForEach($character in $Text.ToCharArray()){\n Write-Progress -Activity \"Testing $Text\" -Status \"Working on $character\" -PercentComplete ($count/($Text.Length)*100) -Id 0\n Convert-TextToImage -Text $character -filename 'C:\\temp\\pic1.png' -Font $font -FontSize $fontSize\n & 'C:\\Program Files\\Tesseract-OCR\\tesseract.exe' 'C:\\temp\\pic1.png' text1 --psm $psm --oem 1 -l eng\n [char](gc 'C:\\temp\\text1.txt').trim()\n $count++\n }\n ([string]$word).replace(' ','')\n }\n End\n {\n }\n}\n \n\n$keys = @()\n$min = 0\n$max = 65535\nForEach($i in $min..$max){\n Write-Progress -Activity \"Checking all chars\" -Status $i -PercentComplete (($i-$min)/($max-$min)*100) -Id 1\n try{\n $temp = Get-OCRByChar -Char $([char]$i)\n }Catch{\n $temp = [char]0\n }\n\n $keys += [pscustomobject]@{\n CharNum = $i\n Char = [char]$i\n LooksLike = $temp\n }\n}\n$keys | Export-Clixml 'C:\\temp\\Keys.xml' \n \n \n At this point, we have a hash table with 65535 Unicode characters as the keys, and the ones they looked like (according to Tesseract) as the values. A few of them were obviously wrong, like ‘-‘ being detected as ‘:’ so I slightly tweaked a few values. If you want to get ambitious you could manually generate a better file. \n \n Convert each item of interest to their Latin character equivalent \n Now that we have a list of words to convert to Latin characters and a hash table with key/value pairs, we simply need to convert every word to the Latic characters it looks like. The short code below changes the $Text string to $result using the $KeyHash hash table. \n \n $result = [string]''\n ForEach ($char in ($Text.ToCharArray())) {\n $result += $KeyHash[[char]$char]\n }\n $result \n \n \n Compare the converted values \n Now that we have the Latin equivalent of every variable, function, and any other items we’re interested in, we can determine if any of them are similar. Then all words are grouped by their Latin equivalent so if there is more than one with the same Latin equivalent but different actual characters, then they look the same but are actually different. \n \n Get-HomoglyphsInFile -FullName .\\TestFile.ps1 -Predefined PowerShell -RemoveUninteresting\n Name OCRValue Type File ---- -------- ---- ---- \n$false $false Variable TestFile.ps1\n$falsе $false Variable TestFile.ps1\n$true $true Variable TestFile.ps1\n$truе $true Variable TestFile.ps1\nFoo2 Foo2 Function TestFile.ps1\nFoо2 FoO2 Function TestFile.ps1 \n \n \n Other uses \n Malware can be converted to characters that look the same, but the code won’t work so code can be analyzed but not executed. \n Malicious students could be using scripts to cheat by automatically changing someone else’s paper that took the class previously. By using homoglyphs, they may be able to have the paper appear identical but avoid detection by the anti-cheating software. \n \n Extensibility \n The homoglyph detection module is extensible. You can write your own parser to parse another language or file format for Get-HomoglyphsInFile to use. \n \n Possible additional work \n \n Expand parsers to work on other popular languages \n Create VSCode extension to automatically detect homoglyphs \n Create Azure Pipeline to automatically scan commits \n Possibly use GitHub actions to scan automatically \n \n While homoglyphs have been around forever and used in attacks with DNS entries, I was unable to find automated scanning to help warn users of homoglyphs. It has been a fun experiment writing this PowerShell module and I hope you enjoy using it and building on it. If you find homoglyphs detection useful I’m interested in what you are using it for and what you found found so post it in the comments below. \n \n Have fun scripting! \n \n Additional reading \n \n Source code repository: https://github.com/PaulHCode/HomoglyphDetection \n PowerShell gallery package: https://www.powershellgallery.com/packages/HomoglyphDetection \n Blog series on Pester testing in PowerShell: https://devblogs.microsoft.com/scripting/unit-testing-powershell-code-with-pester/ \n Abstract Syntax Trees: https://devblogs.microsoft.com/powershell/using-abstract-syntax-trees-asts-with-ise-to-make-scripting-more-productive/ \n Tesseract: https://github.com/tesseract-ocr/tesseract \n Make Homoglyphs: http://homoglyphs.net/ \n Trojan Source White Paper: https://trojansource.codes/ \n ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"19944","kudosSumWeight":3,"repliesCount":2,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDE","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMjAxODIyLTM1NzI4MWlBQjFBMUVGMDFFNjVDNERD?revision=20\"}"}}],"totalCount":1,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"coverImage":null,"coverImageProperties":{"__typename":"CoverImageProperties","style":"STANDARD","titlePosition":"BOTTOM","altText":""}},"CachedAsset:text:en_US-components/community/Navbar-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/community/Navbar-1745505307000","value":{"community":"Community Home","inbox":"Inbox","manageContent":"Manage Content","tos":"Terms of Service","forgotPassword":"Forgot Password","themeEditor":"Theme Editor","edit":"Edit Navigation Bar","skipContent":"Skip to content","gxcuf89792":"Tech Community","external-1":"Events","s-m-b":"Nonprofit Community","windows-server":"Windows Server","education-sector":"Education Sector","driving-adoption":"Driving Adoption","Common-content_management-link":"Content Management","microsoft-learn":"Microsoft Learn","s-q-l-server":"Content Management","partner-community":"Microsoft Partner Community","microsoft365":"Microsoft 365","external-9":".NET","external-8":"Teams","external-7":"Github","products-services":"Products","external-6":"Power Platform","communities-1":"Topics","external-5":"Microsoft Security","planner":"Outlook","external-4":"Microsoft 365","external-3":"Dynamics 365","azure":"Azure","healthcare-and-life-sciences":"Healthcare and Life Sciences","external-2":"Azure","microsoft-mechanics":"Microsoft Mechanics","microsoft-learn-1":"Community","external-10":"Learning Room Directory","microsoft-learn-blog":"Blog","windows":"Windows","i-t-ops-talk":"ITOps Talk","external-link-1":"View All","microsoft-securityand-compliance":"Microsoft Security","public-sector":"Public Sector","community-info-center":"Lounge","external-link-2":"View All","microsoft-teams":"Microsoft Teams","external":"Blogs","microsoft-endpoint-manager":"Microsoft Intune","startupsat-microsoft":"Startups at Microsoft","exchange":"Exchange","a-i":"AI and Machine Learning","io-t":"Internet of Things (IoT)","Common-microsoft365-copilot-link":"Microsoft 365 Copilot","outlook":"Microsoft 365 Copilot","external-link":"Community Hubs","communities":"Products"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarHamburgerDropdown-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarHamburgerDropdown-1745505307000","value":{"hamburgerLabel":"Side Menu"},"localOverride":false},"CachedAsset:text:en_US-components/community/BrandLogo-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/community/BrandLogo-1745505307000","value":{"logoAlt":"Khoros","themeLogoAlt":"Brand Logo"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarTextLinks-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarTextLinks-1745505307000","value":{"more":"More"},"localOverride":false},"CachedAsset:text:en_US-components/authentication/AuthenticationLink-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/authentication/AuthenticationLink-1745505307000","value":{"title.login":"Sign In","title.registration":"Register","title.forgotPassword":"Forgot Password","title.multiAuthLogin":"Sign In"},"localOverride":false},"CachedAsset:text:en_US-components/nodes/NodeLink-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/nodes/NodeLink-1745505307000","value":{"place":"Place {name}"},"localOverride":false},"CachedAsset:text:en_US-components/tags/TagSubscriptionAction-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/tags/TagSubscriptionAction-1745505307000","value":{"success.follow.title":"Following Tag","success.unfollow.title":"Unfollowed Tag","success.follow.message.followAcrossCommunity":"You will be notified when this tag is used anywhere across the community","success.unfollowtag.message":"You will no longer be notified when this tag is used anywhere in this place","success.unfollowtagAcrossCommunity.message":"You will no longer be notified when this tag is used anywhere across the community","unexpected.error.title":"Error - Action Failed","unexpected.error.message":"An unidentified problem occurred during the action you took. Please try again later.","buttonTitle":"{isSubscribed, select, true {Unfollow} false {Follow} other{}}","unfollow":"Unfollow"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/QueryHandler-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/QueryHandler-1745505307000","value":{"title":"Query Handler"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarDropdownToggle-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarDropdownToggle-1745505307000","value":{"ariaLabelClosed":"Press the down arrow to open the menu"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageListTabs-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageListTabs-1745505307000","value":{"mostKudoed":"{value, select, IDEA {Most Votes} other {Most Likes}}","mostReplies":"Most Replies","mostViewed":"Most Viewed","newest":"{value, select, IDEA {Newest Ideas} OCCASION {Newest Events} other {Newest Topics}}","newestOccasions":"Newest Events","mostRecent":"Most Recent","noReplies":"No Replies Yet","noSolutions":"No Solutions Yet","solutions":"Solutions","mostRecentUserContent":"Most Recent","trending":"Trending","draft":"Drafts","spam":"Spam","abuse":"Abuse","moderation":"Moderation","tags":"Tags","PAST":"Past","UPCOMING":"Upcoming","sortBymostRecent":"Sort By Most Recent","sortBymostRecentUserContent":"Sort By Most Recent","sortBymostKudoed":"Sort By Most Likes","sortBymostReplies":"Sort By Most Replies","sortBymostViewed":"Sort By Most Viewed","sortBynewest":"Sort By Newest Topics","sortBynewestOccasions":"Sort By Newest Events","otherTabs":" Messages list in the {tab} for {conversationStyle}","guides":"Guides","archives":"Archives"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageView/MessageViewInline-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageView/MessageViewInline-1745505307000","value":{"bylineAuthor":"{bylineAuthor}","bylineBoard":"{bylineBoard}","anonymous":"Anonymous","place":"Place {bylineBoard}","gotoParent":"Go to parent {name}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/OverflowNav-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/OverflowNav-1745505307000","value":{"toggleText":"More"},"localOverride":false},"CachedAsset:text:en_US-components/users/UserLink-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/users/UserLink-1745505307000","value":{"authorName":"View Profile: {author}","anonymous":"Anonymous"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageSubject-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageSubject-1745505307000","value":{"noSubject":"(no subject)"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageTime-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageTime-1745505307000","value":{"postTime":"Published: {time}","lastPublishTime":"Last Update: {time}","conversation.lastPostingActivityTime":"Last posting activity time: {time}","conversation.lastPostTime":"Last post time: {time}","moderationData.rejectTime":"Rejected time: {time}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeIcon-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeIcon-1745505307000","value":{"contentType":"Content Type {style, select, FORUM {Forum} BLOG {Blog} TKB {Knowledge Base} IDEA {Ideas} OCCASION {Events} other {}} icon"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageUnreadCount-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageUnreadCount-1745505307000","value":{"unread":"{count} unread","comments":"{count, plural, one { unread comment} other{ unread comments}}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageViewCount-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageViewCount-1745505307000","value":{"textTitle":"{count, plural,one {View} other{Views}}","views":"{count, plural, one{View} other{Views}}"},"localOverride":false},"CachedAsset:text:en_US-components/kudos/KudosCount-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/kudos/KudosCount-1745505307000","value":{"textTitle":"{count, plural,one {{messageType, select, IDEA{Vote} other{Like}}} other{{messageType, select, IDEA{Votes} other{Likes}}}}","likes":"{count, plural, one{like} other{likes}}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageRepliesCount-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageRepliesCount-1745505307000","value":{"textTitle":"{count, plural,one {{conversationStyle, select, IDEA{Comment} OCCASION{Comment} other{Reply}}} other{{conversationStyle, select, IDEA{Comments} OCCASION{Comments} other{Replies}}}}","comments":"{count, plural, one{Comment} other{Comments}}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/users/UserAvatar-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/users/UserAvatar-1745505307000","value":{"altText":"{login}'s avatar","altTextGeneric":"User's avatar"},"localOverride":false}}}},"page":"/tags/TagPage/TagPage","query":{"nodeId":"board:CoreInfrastructureandSecurityBlog","tagName":"PaulHarrison"},"buildId":"-gVUpXaWnPcjlrLJZ92B7","runtimeConfig":{"buildInformationVisible":false,"logLevelApp":"info","logLevelMetrics":"info","openTelemetryClientEnabled":false,"openTelemetryConfigName":"o365","openTelemetryServiceVersion":"25.3.0","openTelemetryUniverse":"prod","openTelemetryCollector":"http://localhost:4318","openTelemetryRouteChangeAllowedTime":"5000","apolloDevToolsEnabled":false,"inboxMuteWipFeatureEnabled":false},"isFallback":false,"isExperimentalCompile":false,"dynamicIds":["./components/community/Navbar/NavbarWidget.tsx","./components/community/Breadcrumb/BreadcrumbWidget.tsx","./components/customComponent/CustomComponent/CustomComponent.tsx","./components/tags/TagsHeaderWidget/TagsHeaderWidget.tsx","./components/messages/MessageListForNodeByRecentActivityWidget/MessageListForNodeByRecentActivityWidget.tsx","./components/tags/TagSubscriptionAction/TagSubscriptionAction.tsx","./components/external/components/ExternalComponent.tsx","./components/customComponent/CustomComponentContent/TemplateContent.tsx","../shared/client/components/common/List/ListGroup/ListGroup.tsx","./components/messages/MessageView/MessageView.tsx","./components/messages/MessageView/MessageViewInline/MessageViewInline.tsx"],"appGip":true,"scriptLoader":[{"id":"analytics","src":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/pagescripts/1730819800000/analytics.js?page.id=TagPage","strategy":"afterInteractive"}]}