github
39 TopicsGitHub Administrator Blueprinting Opportunity
Greetings! GitHub is updating a credential for GitHub Administrator, and we need your input through our exam blueprinting survey. The blueprint determines how many questions each skill in the exam will be assigned. Please complete the online survey by October 17, 2025. Please also feel free to forward the survey to any colleagues you consider subject matter experts for this certification. You may send this to people external to Microsoft and GitHub as well. If you have any questions, feel free to contact John Sowles at josowles@microsoft.com or Alicia Gorriaran at aliciagorriaran@github.com. GitHub Administrator blueprint survey link: https://microsoftlearning.co1.qualtrics.com/jfe/form/SV_9st4ir1V8sngkdw Thank you!17Views0likes0CommentsCreate an Active Student badge on Microsoft Learn
Create an Active Student badge on Microsoft Learn Description: I suggest adding an official Active Studentโ badge in the Microsoft Community and Microsoft Learn platforms. This badge would Highlight studentsโ commitment to learning. Encourage continuous participation through visible recognition. Connect learning achievements (Learn) with community contributions (Community Hub). Provide a public credential that can be showcased on a CV or professional profile. Such a symbolic addition would strengthen motivation, visibility, and the bridge between Microsoft Learn and the Community.Solved122Views1like4CommentsCI/CD GitHub Deployment from Dev to UAT Synapse Workspace not Picking Up UAT Resources
Hello, I am setting up CI/CD for Azure Synapse Analytics using GitHub Actions with multiple environments (Dev, UAT, Prod). My Synapse resources are: Dev: ************-dev, azcalsbdatalakedev, calsbvaultdev, SQL DB azcalsbazuresqldev / MetaData UAT: ************-uat, azcalsbdatalakeuat, calsbvaultuat, SQL DB azcalsbazuresqluat / MetaData Prod: ***********-prod, azcalsbdatalakeprod, azcalsbvaultprod, SQL DB azcalsbazuresqlprod / MetaData I have environment-specific parameter override files like uat.json and prod.json. My GitHub workflows (synapse-dev.yml, synapse-uat.yml, etc.) deploy the Synapse publish artifacts (TemplateForWorkspace.json and TemplateParametersForWorkspace.json) with those overrides. Issue: When I run the UAT workflow, deployment completes successfully but the UAT Synapse workspace still shows Dev resources. For example, linked services like LS_ADLS still point to azcalsbdatalakedev instead of azcalsbdatalakeuat. What I have tried: Created overrides for UAT (uat.json) with correct workspace name and connection strings Checked GitHub workflow YAML to confirm the override file is being passed in the az deployment group create step Verified that Dev deployment works fine Tried changing default values in linked services JSON but behavior is inconsistent Questions: Is there a specific way to structure override files (uat.json) for Synapse CI/CD deployments so environment values are correctly replaced? Do I need separate branches in GitHub for Dev, UAT, and Prod, or can I deploy to all environments from main with overrides? Has anyone else seen linked services or parameters still pointing to Dev even after a UAT deployment? Any guidance, best practices, or sample YAML and override examples would be very helpful. Thanks in advance.12Views0likes0Comments๐ From Chessboard to Cloud: My Journey into Azure Security
Hi everyone ๐ I'm Perparim Abdullahu, an Azure Solutions Architect focused on Microsoft 365 & Azure security. I recently joined the Learn Community to share hands-on labs, visual guides, and real-world insights from my journey. I specialize in designing Zero Trust architectures using Microsoft Entra ID (CA, PIM), Intune, Defender, and Purview. Iโm certified in AZ-305, AZ-104, and SC-300, and currently preparing for SC-100. Through #PerparimLabs, Iโve built a growing archive of diagrams, KQL snippets, and โgotchasโ from the field. My goal is to turn complex deployments into clear, visual stories that help others learn faster. ๐ง Coming soon: A visual breakdown of Insider Risk Management with Purview A lab on Conditional Access policies with real-world use cases Excited to learn from this community and contribute back. Letโs build secure, resilient systemsโtogether ๐. #AzureSecurity | #ZeroTrust | #MicrosoftLearn| Microsoft Entra | Conditional Access | #PerparimLabs351Views0likes2Commentsmicrosoft learn programe
I also take courses on Microsoft Learn. In the videos and written tutorials, they explain how to do certain things โ for example, in Power Automate. But often, the version of the program I have on my PC is not the same as the one shown in the videos or instructions. This makes learning difficult. It would be very helpful if Microsoft Learn clearly indicated which version of the software is being used in each tutorial or video.48Views0likes0CommentsNavigating the New AI Landscape: A Developerโs Journey Through the Noise
In this article, I share a developerโs perspective on navigating the ever-expanding landscape of AI tools. Grounded in the familiarity of .NET, we explore how Microsoftโs ecosystemโfrom Semantic Kernel and GitHub Copilot to MCP Server, Fabric, and low-code platformsโoffers not chaos, but clarity. With the right mindset and the right tools, the AI frontier becomes not overwhelming, but empowering.276Views0likes0CommentsSharepoint WorkBooks
I currently have multiple Excel Workbooks that are at multiple locations throughout my area that feed back to my master workbook. I have them all linked. I have to do this monthly so I have to create new month workbooks. The problem is when i save a copy of the current workbooks it starts changing this months information. All I want to do is copy all the information on the workbooks, but change the date without it updating anything else.38Views1like0Commentsdotnet maui blazor hybrid for Local viewer.
Hi Everyone, `Preformatted text` I am a dotnet Developer. Currently working with .net maui blazor hybrid app. I want to create a Local Dicom Viewer using this template for Windows. i have created a simple project as selecting a single dicom file from local drive and showing its metadata and image. Razor Page:: PAGE "/viewer" @inject IJSRuntime JSRuntime <div class="container"> <h1>DICOM Viewer</h1> <div class="row mb-3"> <div class="col"> <div class="input-group"> <InputFile OnChange="@LoadFiles" class="form-control" accept=".dcm" id="selectFile" /> <button @onclick="ResetViewer" class="btn btn-secondary">Reset</button> </div> <div class="mt-2"> <small class="text-muted">Select a DICOM file or drag and drop (if supported)</small> </div> </div> </div> <div class="row"> <div class="col-md-8"> <div id="cornerstone-element" style="width: 100%; height: 500px; border: 1px solid #ccc; position: relative;"> <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: #888;"> Select a DICOM file to view </div> </div> </div> <div class="col-md-4"> <div class="card"> <div class="card-header">DICOM Info</div> <div class="card-body"> <table class="table table-sm"> <tbody> <tr><td>Transfer Syntax:</td><td id="transfersyntax">-</td></tr> <tr><td>SOP Class UID:</td><td id="sopclassuid">-</td></tr> <tr><td>SOP Instance UID:</td><td id="sopinstanceuid">-</td></tr> <tr><td>Rows:</td><td id="rows">-</td></tr> <tr><td>Columns:</td><td id="columns">-</td></tr> <tr><td>Spacing:</td><td id="spacing">-</td></tr> <tr><td>Direction:</td><td id="direction">-</td></tr> <tr><td>Origin:</td><td id="origin">-</td></tr> <tr><td>Modality:</td><td id="modality">-</td></tr> <tr><td>Pixel Representation:</td><td id="pixelrepresentation">-</td></tr> <tr><td>Bits Allocated:</td><td id="bitsallocated">-</td></tr> <tr><td>Bits Stored:</td><td id="bitsstored">-</td></tr> <tr><td>High Bit:</td><td id="highbit">-</td></tr> <tr><td>Photometric Interpretation:</td><td id="photometricinterpretation">-</td></tr> <tr><td>Window Center:</td><td id="windowcenter">-</td></tr> <tr><td>Window Width:</td><td id="windowwidth">-</td></tr> </tbody> </table> </div> </div> </div> </div> </div> @code { protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { try { // Initialize the DICOM viewer using the global interop object await JSRuntime.InvokeVoidAsync("dicomViewerInterop.initDicomViewer"); } catch (Exception ex) { Console.WriteLine($"Error initializing DICOM viewer: {ex.Message}"); } } } private async Task LoadFiles(InputFileChangeEventArgs e) { var file = e.File; if (file != null) { try { // Read the file content using var stream = file.OpenReadStream(maxAllowedSize: 30000000); // Adjust max allowed size if needed using var ms = new MemoryStream(); await stream.CopyToAsync(ms); byte[] fileData = ms.ToArray(); var filename=file.Name; // Send the file data to JS await JSRuntime.InvokeVoidAsync("dicomViewerInterop.loadDicomFileFromArray", fileData, file.Name); } catch (Exception ex) { Console.WriteLine($"Error loading DICOM file: {ex.Message}"); } } } private async Task ResetViewer() { try { await JSRuntime.InvokeVoidAsync("dicomViewerInterop.resetViewer"); } catch (Exception ex) { Console.WriteLine($"Error resetting viewer: {ex.Message}"); } } } Javascript Interop: // Cornerstone interop code for MAUI Blazor // Global variables to store references var cornerstone, cornerstoneTools, dicomImageLoader, dicomParser; var renderingEngine = null; var viewport = null; var toolGroup = null; var initialized = false; var uids = {}; // Initialize the UIds for SOP Class descriptions function initUids() { // Common DICOM UIDs uids = { '1.2.840.10008.5.1.4.1.1.1': 'CR Image Storage', '1.2.840.10008.5.1.4.1.1.1.1': 'Digital X-Ray Image - For Presentation', '1.2.840.10008.5.1.4.1.1.1.1.1': 'Digital X-Ray Image - For Processing', '1.2.840.10008.5.1.4.1.1.2': 'CT Image Storage', '1.2.840.10008.5.1.4.1.1.3.1': 'Ultrasound Multi-frame Image Storage', '1.2.840.10008.5.1.4.1.1.4': 'MR Image Storage', '1.2.840.10008.5.1.4.1.1.6.1': 'Ultrasound Image Storage', '1.2.840.10008.5.1.4.1.1.7': 'Secondary Capture Image Storage', '1.2.840.10008.5.1.4.1.1.128': 'Positron Emission Tomography Image Storage', '1.2.840.10008.5.1.4.1.1.13.1.1': 'X-Ray 3D Angiographic Image Storage', '1.2.840.10008.5.1.4.1.1.13.1.2': 'X-Ray 3D Craniofacial Image Storage', '1.2.840.10008.5.1.4.1.1.13.1.3': 'Breast Tomosynthesis Image Storage' }; } // Check if libraries are loaded function checkLibraryLoading() { console.log("DOM content loaded"); if (typeof dicomViewer === 'undefined') { console.error("dicomViewer bundle is not loaded"); return false; } if (typeof dicomViewer.cornerstoneCore === 'undefined') { console.error(" Cornerstone3D is not loaded"); return false; } if (typeof dicomViewer.cornerstoneTools === 'undefined') { console.error(" CornerstoneTools is not loaded"); return false; } if (typeof dicomViewer.dicomImageLoader === 'undefined') { console.error(" DICOM Image Loader is not loaded"); return false; } if (typeof dicomViewer.dicomParser === 'undefined') { console.error(" DICOM Parser is not loaded"); return false; } return true; } // Initialize volume loader (compatible with Cornerstone3D v3.8.0) async function initVolumeLoader() { try { // Register the volume loader using newer API approach if (cornerstone.volumeLoader) { // Some versions might have this interface cornerstone.volumeLoader.registerUnknownVolumeLoader(); cornerstone.volumeLoader.registerVolumeLoader('dicom', function () { return { loadVolume: function () { return Promise.resolve(null); } }; }); } else { // Fallback for other versions console.log("Using fallback volume loader approach"); } } catch (error) { console.error("Error in initVolumeLoader:", error); } } // Initialize providers async function initProviders() { try { // Simplified initialization for adapting to different versions if (cornerstone.registerVolumeLoader) { cornerstone.registerVolumeLoader('dicomweb', function () { return { loadVolume: function () { return Promise.resolve(null); } }; }); } } catch (error) { console.error("Error in initProviders:", error); } } // Setup HTML function setupHTML() { const element = document.getElementById('cornerstone-element'); if (element) { // Clear any existing content element.innerHTML = ''; // Set up drop zone functionality element.addEventListener('dragover', handleDragOver, false); element.addEventListener('drop', handleFileSelect, false); } return element; } // Drag over handler function handleDragOver(evt) { evt.stopPropagation(); evt.preventDefault(); evt.dataTransfer.dropEffect = 'copy'; // Show as a copy operation } // File drop handler function handleFileSelect(evt) { evt.stopPropagation(); evt.preventDefault(); // Get the file that was dropped const files = evt.dataTransfer.files; if (files.length > 0) { const file = files[0]; // Read the file and load it const reader = new FileReader(); reader.onload = function (e) { const arrayBuffer = e.target.result; loadDicomFileFromArrayBuffer(arrayBuffer, file.name); }; reader.readAsArrayBuffer(file); } } // Initialize the DICOM viewer (called from Blazor) function initDicomViewer() { try { // Check if libraries are loaded if (!checkLibraryLoading()) { return Promise.reject("Libraries not loaded"); } // Assign the libraries from the global bundle cornerstone = dicomViewer.cornerstoneCore; cornerstoneTools = dicomViewer.cornerstoneTools; dicomImageLoader = dicomViewer.dicomImageLoader; dicomParser = dicomViewer.dicomParser; // Init UIDs initUids(); // Initialize image loader return Promise.resolve() .then(() => initVolumeLoader()) .then(() => { // Initialize DICOM image loader if (dicomImageLoader.init) { dicomImageLoader.init(); } return initProviders(); }) .then(() => { // Set CPU rendering for compatibility if (cornerstone.setUseCPURendering) { cornerstone.setUseCPURendering(true); } // Add tools if they exist if (!cornerstoneTools.addTool) { console.warn("Tool functions not available in this version"); return; } // Extract tool classes and enums const PanTool = cornerstoneTools.PanTool; const WindowLevelTool = cornerstoneTools.WindowLevelTool; const StackScrollTool = cornerstoneTools.StackScrollTool; const ZoomTool = cornerstoneTools.ZoomTool; const ToolGroupManager = cornerstoneTools.ToolGroupManager; // Get mouse bindings from enums if available const MouseBindings = cornerstoneTools.Enums?.MouseBindings || { Primary: 1, Auxiliary: 2, Secondary: 3, Wheel: 4 }; // Add tools if (PanTool) cornerstoneTools.addTool(PanTool); if (WindowLevelTool) cornerstoneTools.addTool(WindowLevelTool); if (StackScrollTool) cornerstoneTools.addTool(StackScrollTool); if (ZoomTool) cornerstoneTools.addTool(ZoomTool); // Create tool group if ToolGroupManager exists if (ToolGroupManager && ToolGroupManager.createToolGroup) { const toolGroupId = 'myToolGroup'; toolGroup = ToolGroupManager.createToolGroup(toolGroupId); // Add tools to the group if (WindowLevelTool) toolGroup.addTool(WindowLevelTool.toolName); if (PanTool) toolGroup.addTool(PanTool.toolName); if (ZoomTool) toolGroup.addTool(ZoomTool.toolName); if (StackScrollTool) toolGroup.addTool(StackScrollTool.toolName); // Set tool bindings if (WindowLevelTool) { toolGroup.setToolActive(WindowLevelTool.toolName, { bindings: [{ mouseButton: MouseBindings.Primary, // Left Click }], }); } if (PanTool) { toolGroup.setToolActive(PanTool.toolName, { bindings: [{ mouseButton: MouseBindings.Auxiliary, // Middle Click }], }); } if (ZoomTool) { toolGroup.setToolActive(ZoomTool.toolName, { bindings: [{ mouseButton: MouseBindings.Secondary, // Right Click }], }); } if (StackScrollTool) { toolGroup.setToolActive(StackScrollTool.toolName, { bindings: [{ mouseButton: MouseBindings.Wheel }], }); } } // Setup the HTML element const element = setupHTML(); if (!element) { console.error('Element not found'); return; } // Create the rendering engine if the RenderingEngine class exists if (cornerstone.RenderingEngine) { const renderingEngineId = 'myRenderingEngine'; renderingEngine = new cornerstone.RenderingEngine(renderingEngineId); // Create the viewport const viewportId = 'CT_STACK'; const viewportInput = { viewportId, type: cornerstone.Enums.ViewportType.STACK, element, defaultOptions: { background: [0.2, 0, 0.2], }, }; // Enable the viewport renderingEngine.enableElement(viewportInput); // Get the viewport we created viewport = renderingEngine.getViewport(viewportId); // Add the viewport to the tool group if (toolGroup) { toolGroup.addViewport(viewportId, renderingEngineId); } } else { console.error("RenderingEngine not available"); return; } // Mark as initialized initialized = true; console.log('DICOM viewer initialized successfully'); return Promise.resolve(); }); } catch (error) { console.error('Error initializing DICOM viewer:', error); return Promise.reject(error); } } // Load a DICOM file from an array buffer function loadDicomFileFromArrayBuffer(arrayBuffer, fileName) { if (!initialized || !viewport) { console.error('DICOM viewer not initialized'); return Promise.reject('DICOM viewer not initialized'); } try { // Use the DICOM Image Loader to create an image ID const uint8Array = new Uint8Array(arrayBuffer); let imageId; if (dicomImageLoader.wadouri.fileManager.addByteArray) { imageId = dicomImageLoader.wadouri.fileManager.addByteArray(uint8Array); } else if (dicomImageLoader.wadouri.fileManager.add) { // Create a File-like object const blob = new Blob([uint8Array]); const file = new File([blob], fileName); console.log(file, fileName); imageId = dicomImageLoader.wadouri.fileManager.add(file); console.log(imageId); } else { console.error("No appropriate method to load DICOM file"); return Promise.reject("No appropriate method to load DICOM file"); } // Create a stack with this image const stack = [imageId]; // Set the stack on the viewport viewport.setStack(stack) // Render the image viewport.render(); // Update metadata display updateMetadataDisplay(imageId); console.log('DICOM file loaded successfully:', fileName); // return Promise.resolve(); } catch (error) { console.error('Error loading DICOM file:', error); return Promise.reject(error); } } // Update the metadata display function updateMetadataDisplay(imageId) { try { if (!viewport) return; const imageData = viewport.getImageData(); const { metaData } = cornerstone; // Get metadata from Cornerstone const pixelModule = metaData.get('imagePixelModule', imageId); const voiLutModule = metaData.get('voiLutModule', imageId); const sopCommonModule = metaData.get('sopCommonModule', imageId); const transferSyntax = metaData.get('transferSyntax', imageId); // Update UI elements with the metadata document.getElementById('transfersyntax').innerHTML = transferSyntax?.transferSyntaxUID || '-'; if (sopCommonModule?.sopClassUID) { const sopClassDesc = uids[sopCommonModule.sopClassUID] || 'Unknown'; document.getElementById('sopclassuid').innerHTML = `${sopCommonModule.sopClassUID} [${sopClassDesc}]`; } else { document.getElementById('sopclassuid').innerHTML = '-'; } document.getElementById('sopinstanceuid').innerHTML = sopCommonModule?.sopInstanceUID || '-'; document.getElementById('rows').innerHTML = imageData?.dimensions[0] || '-'; document.getElementById('columns').innerHTML = imageData?.dimensions[1] || '-'; document.getElementById('spacing').innerHTML = imageData?.spacing.join('\\') || '-'; const formattedDirection = imageData?.direction ? imageData.direction.map(x => Math.round(x * 100) / 100).join(',') : '-'; document.getElementById('direction').innerHTML = formattedDirection; const formattedOrigin = imageData?.origin ? imageData.origin.map(x => Math.round(x * 100) / 100).join(',') : '-'; document.getElementById('origin').innerHTML = formattedOrigin; document.getElementById('modality').innerHTML = imageData?.metadata?.Modality || '-'; document.getElementById('pixelrepresentation').innerHTML = pixelModule?.pixelRepresentation || '-'; document.getElementById('bitsallocated').innerHTML = pixelModule?.bitsAllocated || '-'; document.getElementById('bitsstored').innerHTML = pixelModule?.bitsStored || '-'; document.getElementById('highbit').innerHTML = pixelModule?.highBit || '-'; document.getElementById('photometricinterpretation').innerHTML = pixelModule?.photometricInterpretation || '-'; document.getElementById('windowcenter').innerHTML = voiLutModule?.windowCenter || '-'; document.getElementById('windowwidth').innerHTML = voiLutModule?.windowWidth || '-'; } catch (error) { console.error('Error updating metadata display:', error); } } // Load a DICOM file from a byte array (called from Blazor) function loadDicomFileFromArray(byteArray, fileName) { const arrayBuffer = new Uint8Array(byteArray).buffer; return loadDicomFileFromArrayBuffer(arrayBuffer, fileName); } // Reset the viewer function resetViewer() { if (viewport) { viewport.reset(); viewport.render(); // Reset the metadata display const elements = [ 'transfersyntax', 'sopclassuid', 'sopinstanceuid', 'rows', 'columns', 'spacing', 'direction', 'origin', 'modality', 'pixelrepresentation', 'bitsallocated', 'bitsstored', 'highbit', 'photometricinterpretation', 'windowcenter', 'windowwidth' ]; elements.forEach(id => { document.getElementById(id).innerHTML = '-'; }); return Promise.resolve(); } return Promise.reject("Viewport not initialized"); } // Add to window for accessibility from Blazor window.dicomViewerInterop = { initDicomViewer: initDicomViewer, loadDicomFileFromArray: loadDicomFileFromArray, resetViewer: resetViewer }; // Log when the script is loaded console.log("Cornerstone interop script loaded"); // Check if DOM is already loaded, otherwise wait for it if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', checkLibraryLoading); } else { checkLibraryLoading(); } i am able to load the cornerstone modules from my bundle file , but unable to get metadata and unable to render the image.73Views0likes0Comments